﻿/*
	WARNING!

	This script will alter objects and data in the QIC schema.
	Please ensure that you have a valid backup before executing this script.

	Executing QIC Compiler procedures will alter objects in the database.
	It's recommended that you use QIC Script procedures if you are not familiar 
	with QIC.

	Have fun!

*/


SET NOCOUNT ON

PRINT 'CREATE SCHEMA'
BEGIN
	IF SCHEMA_ID('QIC') IS NULL
	BEGIN
		EXEC ('CREATE SCHEMA [QIC]')
	END
END
GO

PRINT 'CLEAN UP CODE'
BEGIN
	DECLARE @SQL nvarchar(max)
	SET @SQL = ''

	SELECT 
		@SQL += 'DROP ' + 
		CASE objects.type 
			WHEN 'P' THEN 'PROCEDURE'
			WHEN 'TF' THEN 'FUNCTION'
			WHEN 'IF' THEN 'FUNCTION'
			WHEN 'FN' THEN 'FUNCTION'
		END + ' ' +
		'QIC.' + QUOTENAME(objects.name) + CHAR(13) + CHAR(10)
	FROM sys.objects objects
	WHERE objects.schema_id = SCHEMA_ID('QIC')
	AND objects.type IN ('P','IF','TF','FN')

	EXEC (@SQL)
END

GO

PRINT 'CLEAN UP TYPES'
BEGIN
	DECLARE @SQL nvarchar(max)
	SET @SQL = ''

	SELECT @SQL += 'DROP TYPE ' + 'QIC.' + QUOTENAME(types.name) + CHAR(13) + CHAR(10)
	FROM sys.types types
	WHERE types.schema_id = SCHEMA_ID('QIC')

	EXEC (@SQL)
END
GO

PRINT 'RECREATE CONFIG'
BEGIN
	DECLARE @XML XML
	DECLARE @Handle INT  
	DECLARE @Exists BIT

	IF OBJECT_ID('qic.Config') IS NOT NULL SET @Exists = 1

	IF @Exists = 1
	BEGIN
		SELECT @XML = (select (select * from qic.Config for xml path('Row'), type) for xml path('Rows'))
		DROP TABLE qic.Config
	END

	CREATE TABLE QIC.[Config] (
		[Name] VARCHAR (50) NOT NULL,
		[MinPrio] INT NULL,
		CONSTRAINT [PK_Config] PRIMARY KEY CLUSTERED ([Name] ASC)
	);

	IF @Exists = 1
	BEGIN
		EXEC sp_xml_preparedocument @handle OUTPUT, @XML  

		INSERT INTO qic.Config (Name, MinPrio)
		SELECT Name, MinPrio
		FROM OPENXML(@handle, '//Rows/Row', 2)  
			WITH (
			Name VARCHAR(50),
			MinPrio INT
			)  

		EXEC sp_xml_removedocument @handle 
	END
END
GO

PRINT 'RECREATE ASPECTCONFIG'
BEGIN
	DECLARE @XML XML
	DECLARE @Handle INT  
	DECLARE @Exists BIT

	IF OBJECT_ID('qic.AspectConfig') IS NOT NULL SET @Exists = 1
	IF @Exists = 1
	BEGIN
		SELECT @XML = (select (select * from qic.AspectConfig for xml path('Row'), type) for xml path('Rows'))
		DROP TABLE qic.AspectConfig
	END

	CREATE TABLE QIC.AspectConfig (
		WhenConfigName VARCHAR (50) NULL,
		WhenSchemaName VARCHAR (50) NULL,
		WhenInterfaceType VARCHAR (50) NULL,
		WhenInterfaceName VARCHAR (50) NULL,
		WhenDelegateName VARCHAR (50) NULL,
		WhenActionName VARCHAR (50) NULL,
		ThenInterfaceName VARCHAR (50) NULL,
		ThenReturnToken VARCHAR (50) NULL,
		ThenTokenMap VARCHAR (50) NULL,
		ThenCallFactory VARCHAR (50) NULL,
		ThenPrio INT NULL
	);

	IF @Exists = 1
	BEGIN
		EXEC sp_xml_preparedocument @handle OUTPUT, @XML  

		INSERT INTO qic.AspectConfig (WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, WhenDelegateName, WhenActionName, ThenInterfaceName, ThenReturnToken, ThenTokenMap, ThenCallFactory, ThenPrio)
		SELECT WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, WhenDelegateName, WhenActionName, ThenInterfaceName, ThenReturnToken, ThenTokenMap, ThenCallFactory, ThenPrio
		FROM OPENXML(@handle, '//Rows/Row', 2)  
			WITH (
				WhenConfigName VARCHAR (50),
				WhenSchemaName VARCHAR (50),
				WhenInterfaceType VARCHAR (50),
				WhenInterfaceName VARCHAR (50),
				WhenDelegateName VARCHAR (50),
				WhenActionName VARCHAR (50),
				ThenInterfaceName VARCHAR (50),
				ThenReturnToken VARCHAR (50),
				ThenTokenMap VARCHAR (50),
				ThenCallFactory VARCHAR (50),
				ThenPrio INT
			)  

		EXEC sp_xml_removedocument @handle 
	END
END
GO

PRINT 'RECREATE DELEGATECONFIG'
BEGIN
	DECLARE @XML XML
	DECLARE @Handle INT  
	DECLARE @Exists BIT

	IF OBJECT_ID('qic.DelegateConfig') IS NOT NULL SET @Exists = 1
	IF @Exists = 1
	BEGIN
		SELECT @XML = (select (select * from qic.DelegateConfig for xml path('Row'), type) for xml path('Rows'))
		DROP TABLE qic.DelegateConfig
	END

	CREATE TABLE QIC.DelegateConfig (
		WhenConfigName VARCHAR (50) NULL,
		WhenSchemaName VARCHAR (50) NULL,
		WhenInterfaceType VARCHAR (50) NULL,
		WhenInterfaceName VARCHAR (50) NULL,
		WhenDelegateName VARCHAR (50) NULL,
		ThenTokenMap VARCHAR (50) NULL,
		ThenCallFactory VARCHAR (50) NULL,
		ThenPrio INT NULL
    
	);

	IF @Exists = 1
	BEGIN
		EXEC sp_xml_preparedocument @handle OUTPUT, @XML  

		INSERT INTO qic.DelegateConfig (WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, WhenDelegateName, ThenTokenMap, ThenCallFactory, ThenPrio)
		SELECT WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, WhenDelegateName, ThenTokenMap, ThenCallFactory, ThenPrio
		FROM OPENXML(@handle, '//Rows/Row', 2)  
			WITH (
				WhenConfigName VARCHAR (50),
				WhenSchemaName VARCHAR (50),
				WhenInterfaceType VARCHAR (50),
				WhenInterfaceName VARCHAR (50),
				WhenDelegateName VARCHAR (50),
				ThenTokenMap VARCHAR (50),
				ThenCallFactory VARCHAR (50),
				ThenPrio INT
			)  

		EXEC sp_xml_removedocument @handle 
	END
END
GO

PRINT 'RECREATE INTERFACECONFIG'
BEGIN
	DECLARE @XML XML
	DECLARE @Handle INT  
	DECLARE @Exists BIT

	IF OBJECT_ID('qic.InterfaceConfig') IS NOT NULL SET @Exists = 1
	IF @Exists = 1
	BEGIN
		SELECT @XML = (select (select * from qic.InterfaceConfig for xml path('Row'), type) for xml path('Rows'))
		DROP TABLE qic.InterfaceConfig
	END

	CREATE TABLE QIC.InterfaceConfig (
		WhenConfigName VARCHAR (50) NULL,
		WhenSchemaName VARCHAR (50) NULL,
		WhenInterfaceType VARCHAR (50) NULL,
		WhenInterfaceName VARCHAR (50) NULL,
		ThenInterfaceFactory VARCHAR (50) NULL,
		ThenPrio INT NULL
	);

	IF @Exists = 1
	BEGIN
		EXEC sp_xml_preparedocument @handle OUTPUT, @XML  

		INSERT INTO qic.InterfaceConfig (WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, ThenInterfaceFactory, ThenPrio)
		SELECT WhenConfigName, WhenSchemaName, WhenInterfaceType, WhenInterfaceName, ThenInterfaceFactory, ThenPrio
		FROM OPENXML(@handle, '//Rows/Row', 2)  
			WITH (
				WhenConfigName VARCHAR (50),
				WhenSchemaName VARCHAR (50),
				WhenInterfaceType VARCHAR (50),
				WhenInterfaceName VARCHAR (50),
				ThenInterfaceFactory VARCHAR (50),
				ThenPrio INT
			)  

		EXEC sp_xml_removedocument @handle 
	END
END
GO

PRINT 'RECREATE TOKENMAP'
BEGIN
	DECLARE @XML XML
	DECLARE @Handle INT  
	DECLARE @Exists BIT

	IF OBJECT_ID('qic.TokenMap') IS NOT NULL SET @Exists = 1
	IF @Exists = 1
	BEGIN
		SELECT @XML = (select (select * from qic.TokenMap for xml path('Row'), type) for xml path('Rows'))
		DROP TABLE qic.TokenMap
	END

	CREATE TABLE QIC.TokenMap (
		TokenMap  VARCHAR (50) NOT NULL,
		WhenToken VARCHAR (50) NOT NULL,
		ThenToken VARCHAR (50) NOT NULL,
		CONSTRAINT [PK_TokenMap] PRIMARY KEY CLUSTERED ([TokenMap] ASC, [WhenToken] ASC)
	);

	IF @Exists = 1
	BEGIN
		EXEC sp_xml_preparedocument @handle OUTPUT, @XML  

		INSERT INTO qic.TokenMap (TokenMap, WhenToken, ThenToken)
		SELECT TokenMap, WhenToken, ThenToken
		FROM OPENXML(@handle, '//Rows/Row', 2)  
			WITH (
				TokenMap VARCHAR (50),
				WhenToken VARCHAR (50),
				ThenToken VARCHAR (50)
			)  

		EXEC sp_xml_removedocument @handle 
	END
END
GO

PRINT 'CREATE TYPES'
BEGIN

	CREATE TYPE QIC.TokenTable AS TABLE (
		[Id] INT IDENTITY (1, 1) NOT NULL,
		[ObjectId] INT NOT NULL,
		[PropertyId] INT NOT NULL,
		[PropertyName] VARCHAR (100) NOT NULL,
		[UserTypeId] INT NOT NULL,
		[Precision] INT NOT NULL,
		[Scale] INT NOT NULL,
		[MaxLength] INT NOT NULL,
		[IsOutPut] BIT NOT NULL,
		[IsReadOnly] BIT NOT NULL);

END
GO

PRINT 'CREATE OBJECTS'
GO

CREATE FUNCTION QIC.TokenSubstitute(@Token QIC.TokenTable READONLY, @SourceToken VARCHAR(50), @TokenMap VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
	DECLARE @TargetToken VARCHAR(50)
 
	IF ISNULL(@TokenMap,'') <> ''
	BEGIN
		SELECT @TargetToken = ThenToken
		FROM QIC.TokenMap tokenmap 
		WHERE TokenMap = @TokenMap 
		AND WhenToken = @SourceToken
 
		SET @TargetToken = ISNULL(@TargetToken,@SourceToken)
 
		IF '''' + REPLACE(@TargetToken,'''','') + '''' <> @TargetToken
		BEGIN
			IF NOT EXISTS (SELECT * FROM @Token WHERE PropertyName = @TargetToken) SET @TargetToken = NULL
		END
	END
	ELSE
	BEGIN
		SET @TargetToken = @SourceToken
		IF NOT EXISTS (SELECT * FROM @Token WHERE PropertyName = @TargetToken) SET @TargetToken = NULL
	END
 
	RETURN ISNULL(@TargetToken,'NULL')
END
GO
CREATE FUNCTION QIC.InterfaceTokenCall(@Token QIC.TokenTable READONLY, @ObjectId INT, @TokenMap VARCHAR(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Parameters VARCHAR(MAX)
 
	SET @Parameters = ''
 
	SELECT @Parameters += 
		QIC.TokenSubstitute(@Token, PropertyName, @TokenMap)
		+ case IsOutPut when 1 then ' OUT' else '' end
		+ ', '
	FROM @Token
	WHERE ObjectId = @ObjectId
	AND PropertyId > 0
	ORDER BY PropertyId
 
	IF @Parameters <> '' SET @Parameters = LEFT(@Parameters,DATALENGTH(@Parameters) - 2)
 
	RETURN @Parameters
 
END
GO
CREATE FUNCTION QIC.LB()
RETURNS VARCHAR(2)
AS
BEGIN
 
	RETURN char(13) + char(10)
 
END
GO
CREATE FUNCTION QIC.ObjectName(@ObjectId INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
 
	SELECT @Retval = QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(OBJECT_NAME(object_id))
	FROM sys.objects WHERE object_id = @ObjectId
 
	RETURN @Retval
 
END
GO
 
 
CREATE FUNCTION QIC.DelegateConfigNameFactory_DEFAULT(@InterfaceName VARCHAR(50), @ObjectName VARCHAR(255))
RETURNS VARCHAR(50)
AS
BEGIN
 
	DECLARE @Name VARCHAR(255)
 
	IF @InterfaceName = @ObjectName RETURN NULL
	IF LEFT(@ObjectName, LEN(@InterfaceName)) <> @InterfaceName RETURN NULL
 
	SET @Name = RIGHT(@ObjectName,LEN(@ObjectName) - LEN(@InterfaceName))
 
	IF CHARINDEX('_',@Name,1) = 0 RETURN NULL
 
	SET @Name = RIGHT(@Name,LEN(@Name) - CHARINDEX('_',@Name,1))
 
	IF @Name = '' SET @Name = NULL
	IF @Name = '_' SET @Name = ''
 
	RETURN @Name
END
GO
 
 
CREATE FUNCTION QIC.DelegateNameFactory_DEFAULT(@InterfaceName VARCHAR(50), @ObjectName VARCHAR(255))
RETURNS VARCHAR(50)
AS
BEGIN
 
	DECLARE @Name VARCHAR(255)
 
	IF @InterfaceName = @ObjectName RETURN NULL
	IF LEFT(@ObjectName, LEN(@InterfaceName)) <> @InterfaceName RETURN NULL
 
	SET @Name = RIGHT(@ObjectName,LEN(@ObjectName) - LEN(@InterfaceName))
 
	IF CHARINDEX('_',@Name,1) = 0 RETURN @Name
 
	RETURN LEFT(@Name,CHARINDEX('_',@Name,1)-1)
END
GO
 
CREATE FUNCTION QIC.InterfaceNameFactory_DEFAULT(@ObjectName VARCHAR(255))
RETURNS VARCHAR(255)
AS
BEGIN
	IF RIGHT(@ObjectName,1) = '_' RETURN @ObjectName
 
	RETURN NULL
END
GO
CREATE FUNCTION QIC.Indent(@Level INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	RETURN REPLACE(SPACE(@Level), ' ', '	')
 
END
GO
CREATE FUNCTION QIC.FormatArg(@Value VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	IF @Value = 'NULL' RETURN @Value
	IF '''' + REPLACE(@Value, '''','') + '''' = @Value RETURN @Value
	IF '[' + REPLACE(REPLACE(@Value, '[','') ,']','') + ']' = @Value RETURN @Value
	IF LEFT(@Value,1) = '@' RETURN @Value
 
	RETURN QUOTENAME(@Value)
 
END
GO
CREATE FUNCTION QIC.AspectAllow(@ActionName VARCHAR(50), @InterfaceType VARCHAR(10), @AspectType VARCHAR(10))
RETURNS BIT
AS
BEGIN
 
	IF @InterfaceType NOT IN ('P','FN','TF','V') RETURN 0
	IF @AspectType NOT IN ('P','FN') RETURN 0
 
	IF @InterfaceType = 'P' AND @ActionName NOT IN ('AFTER','BEFORE') RETURN 0
	IF @InterfaceType = 'FN' AND @ActionName NOT IN ('AFTER','BEFORE') RETURN 0
	IF @InterfaceType = 'TF' AND @ActionName NOT IN ('AFTER','BEFORE') RETURN 0
	IF @InterfaceType = 'V' AND @ActionName NOT IN ('AFTER','AFTER INSERT','AFTER UPDATE','AFTER DELETE','BEFORE','BEFORE INSERT','BEFORE UPDATE','BEFORE DELETE') RETURN 0
 
 
	IF @InterfaceType = 'P' AND @AspectType NOT IN ('P','FN') RETURN 0
	IF @InterfaceType = 'FN' AND @AspectType NOT IN ('FN') RETURN 0
	IF @InterfaceType = 'TF' AND @AspectType NOT IN ('FN') RETURN 0
	IF @InterfaceType = 'V' AND @AspectType NOT IN ('P','FN') RETURN 0
 
	RETURN 1
 
END
GO
CREATE FUNCTION [QIC].[CallFactory_VINSERT](@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @SelectValues VARCHAR(MAX)
	DECLARE @InsertColumns VARCHAR(MAX)
	DECLARE @CalleeView VARCHAR(MAX)
	DECLARE @LocalToken QIC.TokenTable
	DECLARE @TargetToken QIC.TokenTable
 
	SELECT @CalleeView = QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name) from sys.objects WHERE object_id = @CalleeId
 
	INSERT INTO @TargetToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
	SELECT 0,0,0,token.ObjectId,0,token.PropertyId,token.PropertyName,0,0 FROM @Token token
	INNER JOIN sys.columns Targetcolumns
		ON Targetcolumns.object_id = token.ObjectId
		AND Targetcolumns.column_id = token.PropertyId
		AND Targetcolumns.is_computed = 0
		AND Targetcolumns.is_identity = 0
	WHERE token.ObjectId = @CalleeId
 
	SET @InsertColumns = ''
	SELECT @InsertColumns += QUOTENAME(Targetcolumns.PropertyName) + ', '
	FROM @TargetToken Targetcolumns
	ORDER BY Targetcolumns.PropertyId
 
	IF @InsertColumns = '' RETURN ''
	SET @InsertColumns = LEFT(@InsertColumns,DATALENGTH(@InsertColumns) - 2)
 
	INSERT INTO @LocalToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
	SELECT 0,0,0,ObjectId,0,PropertyId,PropertyName,0,0 FROM @Token 
	WHERE ObjectId = @CallerId OR (PropertyName LIKE '@%') OR (PropertyName LIKE '''%''')
 
	SET @SelectValues = ''
	SELECT @SelectValues += QIC.TokenSubstitute(@LocalToken, targetToken.PropertyName, @TokenMap)	+ ', '
	FROM @TargetToken targetToken
	LEFT OUTER JOIN @Token sourceToken
		ON sourceToken.ObjectId = @CallerId
		AND QIC.TokenSubstitute(@LocalToken, sourceToken.PropertyName, @TokenMap) =  targetToken.PropertyName
	WHERE targetToken.ObjectId = @CalleeId
	ORDER BY targetToken.PropertyId
 
	IF @SelectValues <> '' SET @SelectValues = LEFT(@SelectValues,DATALENGTH(@SelectValues) - 2)
	SET @SelectValues = ISNULL(@SelectValues,'')
 
	SET @Call = ''
	SET @Call += 
		QIC.Indent(@Indent) + 'INSERT INTO ' + @CalleeView + ' (' + @InsertColumns + ') ' + QIC.LB() +
		QIC.Indent(@Indent) + 'SELECT ' + @SelectValues + ' FROM inserted'
 
	RETURN @Call
 
END
GO
CREATE FUNCTION QIC.TokenDefine(@Name VARCHAR(MAX), @UserTypeID INT, @Precision INT, @Scale INT, @MaxLength INT, @IsOutPut BIT, @IsReadonly BIT)
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @TypeName VARCHAR(MAX)
	DECLARE @IsUserDefined BIT
	DECLARE @SchemaId INT
 
	SELECT @IsUserDefined = is_user_defined, @TypeName = name, @SchemaId = schema_id
	FROM sys.types WHERE user_type_id = @UserTypeID
 
	SET @Retval = case @Name when '' THEN '' else QIC.FormatArg(@Name) + ' ' end
 
	IF @IsUserDefined = 1
	BEGIN
		SET @Retval += QUOTENAME(SCHEMA_NAME(@SchemaId)) + '.' +  QUOTENAME(@TypeName)
	END
	ELSE
	BEGIN
		SET @Retval += @TypeName
 
		SET @Retval +=
			case
				when @TypeName like '%text' or @TypeName like 'image' or @TypeName like 'sql_variant' or @TypeName like 'xml' or @TypeName like 'BIT' or @TypeName like '%INT' or @TypeName like '%date' or @TypeName like 'date%'
					then ''
				when @TypeName = 'float'
					then '(' + convert(VARCHAR(10), ISNULL(@Precision, 18)) + ')'
				when @TypeName= 'numeric' or @TypeName = 'decimal'
					then '(' + convert(VARCHAR(10), ISNULL(@Precision, 18)) + ',' + convert(VARCHAR(10), ISNULL(@Scale, 0)) + ')'
				when (@TypeName like '%char' or @TypeName like '%binary') AND @MaxLength = -1
					then '(MAX)'
				when @MaxLength is not null
					then '(' + convert(VARCHAR(10), @MaxLength) + ')'
				else ''
			end 
	END
 
	IF @IsOutPut = 1 SET @Retval += ' OUT'
	IF @IsReadonly = 1 SET @Retval += ' READONLY'
 
	RETURN @Retval
 
END
GO
 
CREATE FUNCTION QIC.CallFactory_P(@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
 
	SET @Call = ''
 
	SET @Call += QIC.Indent(@Indent) + 
		'EXEC ' + 
		CASE ISNULL(@ReturnPropertName,'') WHEN '' THEN '' ELSE @ReturnPropertName + ' = ' END  + 
		QIC.ObjectName(@CalleeId) + ' ' + QIC.InterfaceTokenCall(@Token, @CalleeId, @TokenMap)
 
	RETURN @Call
END
GO
 
CREATE FUNCTION QIC.CallFactory_FN(@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	
	SET @Call = ''
 
	IF ISNULL(@ReturnPropertName,'') = ''
	BEGIN
		SET @Call += QIC.Indent(@Indent) + 'RETURN ' + QIC.ObjectName(@CalleeId) + ' (' + QIC.InterfaceTokenCall(@Token, @CalleeId, @TokenMap) + ')'
	END
	ELSE
	BEGIN
		SET @Call += QIC.Indent(@Indent) + 'SET ' + @ReturnPropertName + ' = ' + QIC.ObjectName(@CalleeId) + ' (' + QIC.InterfaceTokenCall(@Token, @CalleeId, @TokenMap) + ')'
	END
 
	RETURN @Call
 
END
GO
 
CREATE FUNCTION QIC.CallFactory_IF(@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @ReturnMap VARCHAR(MAX)
	DECLARE @CallMap VARCHAR(MAX)
	DECLARE @LocalToken QIC.TokenTable
 
	IF @CalleeId IS NULL OR @CallerId = @CalleeId
	BEGIN
		SET @ReturnMap = ''
		SELECT @ReturnMap += 'CAST(NULL AS ' + QIC.TokenDefine('',Targetcolumns.user_type_id, Targetcolumns.precision, Targetcolumns.scale, Targetcolumns.max_length,0,0)  + ') AS ' + QIC.FormatArg(Targetcolumns.name) + ', '
		FROM sys.columns Targetcolumns
		WHERE Targetcolumns.object_id = @CallerId
		ORDER BY Targetcolumns.column_id
 
		IF @ReturnMap <> '' SET @ReturnMap = LEFT(@ReturnMap,DATALENGTH(@ReturnMap) - 2)
		SET @ReturnMap = ISNULL(@ReturnMap,'')
 
		SET @Call = ''
		SET @Call += QIC.Indent(@Indent) + 'SELECT ' + @ReturnMap
 
	END
	ELSE
	BEGIN
		INSERT INTO @LocalToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
		SELECT 0,0,0,ObjectId,0,PropertyId,PropertyName,0,0 FROM @Token
		UNION ALL
		SELECT 0,0,0,object_id,0,column_id,name,0,0 FROM sys.columns
		WHERE object_id = @CalleeId
 
		SET @ReturnMap = ''
		SELECT @ReturnMap += 
			CASE ISNULL(SourceColumns.name, QIC.TokenSubstitute(@LocalToken, Targetcolumns.name, @TokenMap)) 
				WHEN 'NULL' THEN 'CAST(NULL AS ' + QIC.TokenDefine('',Targetcolumns.user_type_id, Targetcolumns.precision, Targetcolumns.scale, Targetcolumns.max_length,0,0)  + ') AS ' + QIC.FormatArg(Targetcolumns.name)
				ELSE QIC.FormatArg(ISNULL(SourceColumns.name, QIC.TokenSubstitute(@LocalToken, Targetcolumns.name, @TokenMap)))
			END + ', '
		FROM sys.columns Targetcolumns
		LEFT OUTER JOIN sys.columns SourceColumns
			ON SourceColumns.object_id = @CalleeId
			AND QIC.TokenSubstitute(@LocalToken, SourceColumns.name, @TokenMap) =  Targetcolumns.name
		WHERE Targetcolumns.object_id = @CallerId
		ORDER BY Targetcolumns.column_id
 
		IF @ReturnMap <> '' SET @ReturnMap = LEFT(@ReturnMap,DATALENGTH(@ReturnMap) - 2)
		SET @ReturnMap = ISNULL(@ReturnMap,'')
 
 
		SET @CallMap = ''
		SELECT @CallMap += QIC.TokenSubstitute(@LocalToken, TargetParameters.name, @TokenMap) + ', '
		FROM sys.parameters TargetParameters 
		LEFT OUTER JOIN sys.parameters SourceParameters
			ON SourceParameters.object_id = @CallerId
			AND QIC.TokenSubstitute(@LocalToken, SourceParameters.name, @TokenMap) =  TargetParameters.name
		WHERE TargetParameters.object_id = @CalleeId
		ORDER BY TargetParameters.parameter_id
 
		IF @CallMap <> '' SET @CallMap = LEFT(@CallMap,DATALENGTH(@CallMap) - 2)
		SET @CallMap = ISNULL(@CallMap,'')
 
		SET @Call = ''
		SET @Call += QIC.Indent(@Indent) + 
			'SELECT ' + @ReturnMap + ' FROM ' + 
			QIC.ObjectName(@CalleeId) +
			' (' + @CallMap + ')'
	END
 
	RETURN @Call
 
END
GO
CREATE FUNCTION [QIC].[DelegateConfigNameFactory_] (@InterfaceName varchar(50), @ObjectName varchar(255))
RETURNS varchar(50)
AS
BEGIN
 
	--DEFAULT
	RETURN [QIC].[DelegateConfigNameFactory_DEFAULT] (@InterfaceName, @ObjectName)
 
END
GO
CREATE FUNCTION [QIC].[DelegateNameFactory_] (@InterfaceName varchar(50), @ObjectName varchar(255))
RETURNS varchar(50)
AS
BEGIN
 
	--DEFAULT
	RETURN [QIC].[DelegateNameFactory_DEFAULT] (@InterfaceName, @ObjectName)
 
END
GO
CREATE FUNCTION [QIC].[InterfaceNameFactory_] (@ObjectName varchar(255))
RETURNS varchar(255)
AS
BEGIN
 
	--DEFAULT
	RETURN [QIC].[InterfaceNameFactory_DEFAULT] (@ObjectName)
 
END
GO
CREATE FUNCTION QIC.CallFactory_TF(@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @TargetMap VARCHAR(MAX)
	DECLARE @SourceMap VARCHAR(MAX)
	DECLARE @LocalToken QIC.TokenTable
 
	SET @TargetMap = ''
 
	INSERT INTO @LocalToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
	SELECT 0,0,0,ObjectId,0,PropertyId,PropertyName,0,0 FROM @Token
	UNION ALL
	SELECT 0,0,0,object_id,0,column_id,name,0,0 FROM sys.columns
	WHERE object_id = @CalleeId
 
 
	SELECT @TargetMap += QIC.FormatArg(Targetcolumns.name) + ', '
	FROM sys.columns Targetcolumns
	WHERE Targetcolumns.object_id = @CallerId
	ORDER BY Targetcolumns.column_id
 
	IF @TargetMap <> '' SET @TargetMap = LEFT(@TargetMap,DATALENGTH(@TargetMap) - 2)
	
	SET @SourceMap = ''
	SELECT @SourceMap += ISNULL(SourceColumns.name, QIC.FormatArg(QIC.TokenSubstitute(@LocalToken, Targetcolumns.name, @TokenMap))) + ', '
	FROM sys.columns Targetcolumns
	LEFT OUTER JOIN sys.columns SourceColumns
		ON SourceColumns.object_id = @CalleeId
		AND QIC.TokenSubstitute(@LocalToken, SourceColumns.name, @TokenMap) =  Targetcolumns.name
	WHERE Targetcolumns.object_id = @CallerId
	ORDER BY Targetcolumns.column_id
 
	IF @SourceMap <> '' SET @SourceMap = LEFT(@SourceMap,DATALENGTH(@SourceMap) - 2)
 
	SET @SourceMap = ISNULL(@SourceMap,'')
 
	SET @Call = ''
 
	SET @Call += QIC.Indent(@Indent) + 
		'INSERT INTO ' + @ReturnPropertName + '(' + @TargetMap +  ') ' + 
		'SELECT ' + @SourceMap + ' FROM ' + 
		QIC.ObjectName(@CalleeId) +
		' (' + QIC.InterfaceTokenCall(@Token, @CalleeId, @TokenMap) + ')'
 
	RETURN @Call
 
END
GO
CREATE FUNCTION [QIC].[CallFactory_V](@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @ReturnMap VARCHAR(MAX)
	DECLARE @LocalToken QIC.TokenTable
 
	IF @CalleeId IS NULL OR @CallerId = @CalleeId
	BEGIN
		SET @ReturnMap = ''
		SELECT @ReturnMap += 'CAST(NULL AS ' + QIC.TokenDefine('',Targetcolumns.user_type_id, Targetcolumns.precision, Targetcolumns.scale, Targetcolumns.max_length,0,0)  + ') AS ' + QIC.FormatArg(Targetcolumns.name) + ', '
		FROM sys.columns Targetcolumns
		WHERE Targetcolumns.object_id = @CallerId
		ORDER BY Targetcolumns.column_id
 
		IF @ReturnMap <> '' SET @ReturnMap = LEFT(@ReturnMap,DATALENGTH(@ReturnMap) - 2)
		SET @ReturnMap = ISNULL(@ReturnMap,'')
 
		SET @Call = ''
		SET @Call += QIC.Indent(@Indent) + 'SELECT ' + @ReturnMap
 
	END
	ELSE
	BEGIN
		INSERT INTO @LocalToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
		SELECT 0,0,0,ObjectId,0,PropertyId,PropertyName,0,0 FROM @Token WHERE ObjectId = @CalleeId
 
		SET @ReturnMap = ''
		SELECT @ReturnMap += 
			CASE Targetcolumns.name 
			WHEN 'DelegateName' THEN QUOTENAME(@CalleeDelegateName,'''')
			ELSE
				CASE ISNULL(SourceColumns.name, QIC.TokenSubstitute(@LocalToken, Targetcolumns.name, @TokenMap)) 
					WHEN 'NULL' THEN 'CAST(NULL AS ' + QIC.TokenDefine('',Targetcolumns.user_type_id, Targetcolumns.precision, Targetcolumns.scale, Targetcolumns.max_length,0,0)  + ')'
					ELSE QIC.FormatArg(ISNULL(SourceColumns.name, QIC.TokenSubstitute(@LocalToken, Targetcolumns.name, @TokenMap)))
				END 
			END
			+ ', '
		FROM sys.columns Targetcolumns
		LEFT OUTER JOIN sys.columns SourceColumns
			ON SourceColumns.object_id = @CalleeId
			AND QIC.TokenSubstitute(@LocalToken, SourceColumns.name, @TokenMap) =  Targetcolumns.name
		WHERE Targetcolumns.object_id = @CallerId
		ORDER BY Targetcolumns.column_id
 
		IF @ReturnMap <> '' SET @ReturnMap = LEFT(@ReturnMap,DATALENGTH(@ReturnMap) - 2)
		SET @ReturnMap = ISNULL(@ReturnMap,'')
 
 
		SET @Call = ''
		SET @Call += QIC.Indent(@Indent) + 
			'SELECT ' + @ReturnMap + ' FROM ' + 
			QIC.ObjectName(@CalleeId) 
	END
 
	RETURN @Call
 
END
GO
CREATE FUNCTION [QIC].[TokenDeclare](@Token QIC.TokenTable READONLY, @ObjectId INT, @Indent INT)
RETURNS VARCHAR(MAX)
AS
BEGIN

	DECLARE @ReturnValue VARCHAR(MAX)
	DECLARE @XMLColumns VARCHAR(MAX)
	DECLARE @MissingProperty QIC.TokenTable 
	DECLARE @IsView bit

	IF EXISTS (select * from sys.objects where object_id = @ObjectId and type = 'V' ) SET @IsView = 1
	ELSE SET @IsView = 0

	-- MISSING PROPERTY
	BEGIN
		INSERT INTO @MissingProperty (ObjectId,PropertyId,PropertyName,UserTypeId,Precision,Scale,MaxLength,IsOutPut,IsReadOnly)
		SELECT 
			0,
			0,
			property.PropertyName,
			property.UserTypeId,
			property.Precision,
			property.Scale,
			property.MaxLength,
			0,
			0
		FROM @Token property
		INNER JOIN 
			(
				SELECT 
					missingproperty.Id,
					ROW_NUMBER() OVER (PARTITION BY missingproperty.PropertyName Order by missingproperty.Id) Ranking
				FROM @Token missingproperty
				LEFT OUTER JOIN @Token interfaceproperty
					ON interfaceproperty.ObjectId = @ObjectId
					AND interfaceproperty.PropertyName = missingproperty.PropertyName
					AND interfaceproperty.PropertyId > 0
				WHERE interfaceproperty.Id is null
			) missingproperty
			ON missingproperty.Id = property.Id
			AND Ranking = 1
			AND property.PropertyName like '@%'		
		ORDER BY property.Id
	
		SET @ReturnValue = ''

		SELECT @ReturnValue += 
			QIC.Indent(@Indent) + 'DECLARE ' +
			QIC.TokenDefine(PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly) +
			QIC.LB()
		FROM @MissingProperty missingproperty
		ORDER BY missingproperty.Id
	END

	-- SPECIAL PROPERTY
	BEGIN

		IF EXISTS (select * from @MissingProperty where PropertyName = '@InterfaceId') 
			SET @ReturnValue += QIC.Indent(@Indent) + 'SET @InterfaceId = ' + CAST(@ObjectId as varchar(max)) + QIC.LB()
		IF EXISTS (select * from @MissingProperty where PropertyName = '@InterfaceName') 
			SET @ReturnValue += QIC.Indent(@Indent) + 'SET @InterfaceName = ' + QUOTENAME(OBJECT_NAME(@ObjectId),'''') + QIC.LB()

		IF EXISTS (select * from @MissingProperty where PropertyName = '@InterfaceContext') 
		BEGIN
			IF @IsView = 1
			BEGIN
				SET @XMLColumns = ''

				SELECT @XMLColumns += QUOTENAME(PropertyName) + ' AS ' + QUOTENAME(REPLACE(PropertyName,' ','-')) + ',' from @Token where ObjectId = @ObjectId order by PropertyId

				SET @XMLColumns = LEFT(@XMLColumns, DATALENGTH(@XMLColumns) -1)

				SET @ReturnValue += QIC.Indent(@Indent) + 'SET @InterfaceContext = (SELECT '
				SELECT @ReturnValue += '(SELECT ' + @XMLColumns+ ' FROM Inserted FOR XML PATH(''Inserted''), TYPE) Inserted, (SELECT ' + @XMLColumns+ ' FROM Deleted FOR XML PATH(''Deleted''), TYPE) Deleted FOR XML PATH(''InterfaceContext'')'
				SET @ReturnValue += ')' + QIC.LB()
			END
			ELSE
			BEGIN
				SET @ReturnValue += QIC.Indent(@Indent) + 'SET @InterfaceContext = (SELECT '
			
				SELECT @ReturnValue += 
					CASE types.is_table_type 
						WHEN 1 THEN '(select * from ' + token.PropertyName + ' FOR XML PATH(''' + TYPE_NAME(types.user_type_id) + '''), TYPE)'
						ELSE token.PropertyName
					END +
					' ' + QUOTENAME(REPLACE(token.PropertyName,'@','')) + ', '
				FROM @Token token
				LEFT OUTER JOIN sys.types types
					on types.user_type_id = token.UserTypeId
				WHERE token.ObjectId = @ObjectId
				AND token.PropertyId > 0
				ORDER BY token.Id

				IF @@ROWCOUNT <> 0 
				BEGIN
					SET @ReturnValue = LEFT(@ReturnValue,DATALENGTH(@ReturnValue) - 2)
				END
				ELSE
				BEGIN
					SET @ReturnValue += 'NULL'
				END

				SET @ReturnValue += ' FOR XML PATH(''InterfaceContext''))' + QIC.LB()

			END
		END

	END

	IF @ReturnValue <> '' SET @ReturnValue = LEFT(@ReturnValue,DATALENGTH(@ReturnValue) - 2)

	RETURN @ReturnValue

END
GO
CREATE FUNCTION QIC.InterfaceTokenDefine(@Token QIC.TokenTable READONLY, @ObjectId INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Parameters VARCHAR(MAX)
 
	SET @Parameters = ''
 
	SELECT @Parameters += QIC.TokenDefine(PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly) + ', '
	FROM @Token 
	WHERE ObjectId = @ObjectId
	and PropertyId > 0
	ORDER BY Id
 
	IF @Parameters <> '' SET @Parameters = LEFT(@Parameters,DATALENGTH(@Parameters) - 2)
 
	RETURN @Parameters
END
GO
CREATE FUNCTION QIC.ObjectReturnToken(@ObjectId INT)
RETURNS TABLE
AS
RETURN
(
	SELECT 
		ISNULL(parameters.parameter_id,0) PropertyId, 
		ISNULL(parameters.user_type_id,TYPE_ID('INT')) UserTypeId, 
		ISNULL(parameters.precision,10) Precision, 
		ISNULL(parameters.scale,0) Scale, 
		ISNULL(parameters.max_length,4) MaxLength,
		CAST(0 AS Bit) IsOutPut,
		CAST(0 AS Bit) IsReadOnly
	FROM sys.objects objects
	LEFT OUTER JOIN sys.parameters parameters
		ON objects.type = 'FN'
		AND parameters.object_id = objects.object_id
		AND parameters.parameter_id = 0
	WHERE objects.type in ('FN','P')
	AND objects.object_id = @ObjectId
);
GO
 
CREATE FUNCTION [QIC].[Interface_DEFAULT](@ConfigName VARCHAR(50))
RETURNS TABLE
AS
RETURN
(
	SELECT 
		Interface.SchemaName,
		Interface.InterfaceName,
		Interface.InterfaceType,
		Interface.InterfaceFactory,
		Interface.InterfaceId,
		Interface.SchemaId		
	FROM
	(	
		SELECT
			Interface.SchemaName,
			Interface.InterfaceName,
			Interface.InterfaceType,
			Interface.InterfaceId,
			Interface.SchemaId,
			ISNULL(InterfaceConfig.ThenInterfaceFactory,Interface.InterfaceType) InterfaceFactory,
			ROW_NUMBER() OVER (PARTITION BY Interface.InterfaceName Order by InterfaceConfig.ThenPrio desc) Ranking
		FROM
		(
			SELECT 
				schemas.name SchemaName,
				QIC.InterfaceNameFactory_(Interface.name) InterfaceName,
				Interface.type InterfaceType,
				Interface.object_id InterfaceId,
				Interface.schema_id SchemaId
			FROM sys.objects Interface
			INNER JOIN sys.schemas schemas
				ON schemas.schema_id = Interface.schema_id
			WHERE Interface.type in ('FN','P','IF','TF','V')
 
		) Interface
		LEFT OUTER JOIN QIC.Config Config
			ON Config.Name = @ConfigName
		LEFT OUTER JOIN QIC.InterfaceConfig InterfaceConfig
			ON (InterfaceConfig.WhenConfigName IS NULL OR InterfaceConfig.WhenConfigName = Config.Name)
			AND (InterfaceConfig.WhenSchemaName IS NULL OR InterfaceConfig.WhenSchemaName = Interface.SchemaName)
			AND (InterfaceConfig.WhenInterfaceName IS NULL OR InterfaceConfig.WhenInterfaceName = Interface.InterfaceName)
			AND (InterfaceConfig.WhenInterfaceType IS NULL OR InterfaceConfig.WhenInterfaceType COLLATE DATABASE_DEFAULT = Interface.InterfaceType COLLATE DATABASE_DEFAULT)
		WHERE Interface.InterfaceName IS NOT NULL
		AND (ISNULL(InterfaceConfig.ThenPrio,0) >= ISNULL(Config.MinPrio,0)) 
 
	) Interface
	WHERE Interface.Ranking = 1
 
);
GO
CREATE FUNCTION [QIC].[Interface_](@ConfigName varchar(50))
RETURNS TABLE 
AS
RETURN
(
	SELECT [SchemaName], [InterfaceName], [InterfaceType], [InterfaceFactory], [InterfaceId], [SchemaId] FROM [QIC].[Interface_DEFAULT] (@ConfigName)
	
);
GO
CREATE FUNCTION QIC.Delegate_DEFAULT(@ConfigName VARCHAR(50))
RETURNS TABLE
AS
RETURN
(
	SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateId,
			Delegate.DelegateName,
			Delegate.DelegateSchemaName,
			Delegate.TokenMap,
			Delegate.CallFactory
	FROM 
	(
		SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateId,
			Delegate.DelegateName,
			Delegate.DelegateSchemaName,
			DelegateConfig.ThenTokenMap TokenMap,
			REPLACE(CAST(ISNULL(DelegateConfig.ThenCallFactory,Delegate.InterfaceType) as VARCHAR(50)),' ' ,'') CallFactory,
			ROW_NUMBER() OVER (PARTITION BY Delegate.InterfaceName,  Delegate.DelegateName Order by DelegateConfig.ThenPrio desc, Delegate.DelegateConfigName desc) Ranking
		FROM 
		(
			SELECT 
				Interface.InterfaceId InterfaceId,
				Interface.InterfaceName InterfaceName,
				Interface.InterfaceType,
				Interface.SchemaName InterfaceSchemaName,
				Delegate.object_id DelegateId,
				QIC.DelegateNameFactory_(Interface.InterfaceName,Delegate.name) DelegateName,
				QIC.DelegateConfigNameFactory_(Interface.InterfaceName,Delegate.name) DelegateConfigName,
				schemas.name DelegateSchemaName
			FROM QIC.Interface_(@ConfigName) Interface
			INNER JOIN sys.objects Delegate
				ON Interface.InterfaceType = Delegate.type
			INNER JOIN sys.schemas schemas
				ON schemas.schema_id = Delegate.schema_id
		) Delegate
		LEFT OUTER JOIN QIC.Config Config
			ON Config.Name = @ConfigName
		LEFT OUTER JOIN QIC.DelegateConfig DelegateConfig
			ON (DelegateConfig.WhenConfigName IS NULL OR DelegateConfig.WhenConfigName = Config.Name)
			AND (DelegateConfig.WhenSchemaName IS NULL OR DelegateConfig.WhenSchemaName = Delegate.DelegateSchemaName)
			AND (DelegateConfig.WhenDelegateName IS NULL OR DelegateConfig.WhenDelegateName = Delegate.DelegateName)
			AND (DelegateConfig.WhenInterfaceName IS NULL OR DelegateConfig.WhenInterfaceName = Delegate.InterfaceName)
			AND (DelegateConfig.WhenInterfaceType IS NULL OR DelegateConfig.WhenInterfaceType COLLATE DATABASE_DEFAULT = Delegate.InterfaceType COLLATE DATABASE_DEFAULT)
		WHERE Delegate.DelegateName is not null
		AND (Delegate.DelegateConfigName IS NULL OR Delegate.DelegateConfigName = @ConfigName)
		AND (ISNULL(DelegateConfig.ThenPrio,0) >= ISNULL(Config.MinPrio,0))
	) Delegate
	WHERE Delegate.Ranking = 1
);
GO
CREATE FUNCTION [QIC].[Delegate_](@ConfigName varchar(50))
RETURNS TABLE 
AS
RETURN
(
	SELECT [InterfaceId], [InterfaceName], [InterfaceType], [InterfaceSchemaName], [DelegateId], [DelegateName], [DelegateSchemaName], [TokenMap], [CallFactory] FROM [QIC].[Delegate_DEFAULT] (@ConfigName)
	
);
GO
CREATE FUNCTION [QIC].[Aspect_DEFAULT](@ConfigName VARCHAR(50))
RETURNS TABLE
AS
RETURN
(
	SELECT 
		Aspect.InterfaceId,
		Aspect.InterfaceName,
		Aspect.InterfaceType,
		Aspect.InterfaceSchemaName,
		Aspect.DelegateName,
		Aspect.ActionName,
		Aspect.AspectName,
		Aspect.TokenMap,
		Aspect.AspectId,
		Aspect.AspectType,
		Aspect.AspectReturnToken,
		Aspect.CallFactory,
		ROW_NUMBER() OVER (PARTITION BY Aspect.InterfaceName, Aspect.DelegateName, Aspect.ActionName ORDER BY Aspect.Prio DESC) SortOrder
	FROM 
	(
		SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName,
			AspectConfig.WhenActionName ActionName,
			Aspect.InterfaceName AspectName,
			Aspect.InterfaceId AspectId,
			AspectConfig.ThenTokenMap TokenMap,
			AspectConfig.ThenReturnToken AspectReturnToken,
			Aspect.InterfaceType AspectType,
			REPLACE(CAST(ISNULL(AspectConfig.ThenCallFactory,Aspect.InterfaceType) AS VARCHAR(50)), ' ', '') CallFactory,
			MAX(AspectConfig.ThenPrio) Prio
		FROM (
			SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName
			FROM QIC.Delegate_(@ConfigName) Delegate
			GROUP BY 
				Delegate.InterfaceId,
				Delegate.InterfaceName,
				Delegate.InterfaceType,
				Delegate.InterfaceSchemaName,
				Delegate.DelegateName
			UNION ALL
			SELECT 
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.SchemaName InterfaceSchemaName,
			'' DelegateName
			FROM QIC.Interface_(@ConfigName) Delegate
			GROUP BY 
				Delegate.InterfaceId,
				Delegate.InterfaceName,
				Delegate.InterfaceType,
				Delegate.SchemaName
		) Delegate
		LEFT OUTER JOIN QIC.Config Config
			ON Config.Name = @ConfigName
		INNER JOIN QIC.AspectConfig AspectConfig
			ON (AspectConfig.WhenConfigName IS NULL OR AspectConfig.WhenConfigName = Config.Name)
			AND (AspectConfig.WhenSchemaName IS NULL OR AspectConfig.WhenSchemaName = Delegate.InterfaceSchemaName)
			AND ((AspectConfig.WhenDelegateName IS NULL AND Delegate.DelegateName <> '') OR AspectConfig.WhenDelegateName = Delegate.DelegateName)
			AND (AspectConfig.WhenInterfaceName IS NULL OR AspectConfig.WhenInterfaceName = Delegate.InterfaceName)
			AND (AspectConfig.WhenInterfaceType IS NULL OR AspectConfig.WhenInterfaceType COLLATE DATABASE_DEFAULT = Delegate.InterfaceType COLLATE DATABASE_DEFAULT)
		INNER JOIN QIC.Interface_(@ConfigName) Aspect
			ON Aspect.InterfaceName = AspectConfig.ThenInterfaceName
			AND QIC.AspectAllow(AspectConfig.WhenActionName, Delegate.InterfaceType, Aspect.InterfaceType) = 1
		WHERE (ISNULL(AspectConfig.ThenPrio,0) >= ISNULL(Config.MinPrio,0))
		AND Delegate.InterfaceId <> Aspect.InterfaceId
		GROUP BY
			Delegate.InterfaceId,
			Delegate.InterfaceName,
			Delegate.InterfaceType,
			Delegate.InterfaceSchemaName,
			Delegate.DelegateName,
			AspectConfig.WhenActionName,
			Aspect.InterfaceName,
			Aspect.InterfaceId,
			AspectConfig.ThenTokenMap,
			AspectConfig.ThenReturnToken,
			AspectConfig.ThenCallFactory,
			Aspect.InterfaceType
	) Aspect
	
);
GO
CREATE FUNCTION [QIC].[Aspect_](@ConfigName varchar(50))
RETURNS TABLE 
AS
RETURN
(
	SELECT [InterfaceId], [InterfaceName], [InterfaceType], [InterfaceSchemaName], [DelegateName], [ActionName], [AspectId], [AspectName], [AspectType], [TokenMap], [AspectReturnToken], [CallFactory], [SortOrder] FROM [QIC].[Aspect_DEFAULT] (@ConfigName)
	
);
GO
CREATE FUNCTION QIC.[Split] (@String NVARCHAR(MAX), @Separator NVARCHAR(32))
RETURNS @Retval TABLE (String VARCHAR(MAX))   
AS
BEGIN
    DECLARE @xml XML
    SET @XML = N'<root><string>' + REPLACE(@String, @Separator, '</string><string>') + '</string></root>'
 
    INSERT INTO @Retval(String)
    SELECT string.value('.','NVARCHAR(MAX)') AS Item
    FROM @xml.nodes('//root/string') AS RECORDS(string)
 
    RETURN
END
GO
CREATE FUNCTION QIC.KeyResolve_DEFAULT (@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @TokenMap VARCHAR(50))
RETURNS @Keys TABLE (CallerPropertyName VARCHAR(50), CalleePropertyName VARCHAR(50))
AS
BEGIN
 
	DECLARE @KeyName VARCHAR(100)
	DECLARE @CallerName VARCHAR(100)
 
	SELECT @CallerName = OBJECT_NAME(@CallerId)
 
	DECLARE @MatchKeys TABLE (Id tinyint IDENTITY(1,1), CallerPropertyName VARCHAR(50), CalleePropertyName VARCHAR(50))
 
	INSERT INTO @MatchKeys (CallerPropertyName, CalleePropertyName) VALUES
	(@CallerName + 'ID', @CallerName + 'ID'),
	(REPLACE(@CallerName,'_','') + 'ID',REPLACE(@CallerName,'_','') + 'ID'),
	('ID','ID'),
	('ID', @CallerName + 'ID'),
	('ID',REPLACE(@CallerName,'_','') + 'ID')
 
	INSERT INTO @Keys (CallerPropertyName,CalleePropertyName)
	SELECT TOP 1 callerToken.PropertyName, calleeToken.PropertyName FROM @MatchKeys matchkeys
	inner join @Token callerToken
		on callerToken.ObjectId = @CallerId
		and callerToken.PropertyName = matchkeys.CallerPropertyName
	inner join @Token calleeToken
		on calleeToken.ObjectId = @CalleeId
		and calleeToken.PropertyName = matchkeys.CalleePropertyName
	order by matchkeys.Id
 
	RETURN
 
END
GO
CREATE FUNCTION [QIC].[KeyResolve_] (@Token [QIC].[TokenTable] READONLY, @CallerId int, @CalleeId int, @TokenMap varchar(50))
RETURNS @InterfaceReturn TABLE ([CallerPropertyName] varchar(50), [CalleePropertyName] varchar(50))
AS
BEGIN
 
	--DEFAULT
	INSERT INTO @InterfaceReturn([CallerPropertyName], [CalleePropertyName]) SELECT CallerPropertyName, CalleePropertyName FROM [QIC].[KeyResolve_DEFAULT] (@Token, @CallerId, @CalleeId, @TokenMap)
	RETURN
 
END
GO
CREATE FUNCTION [QIC].[CallFactory_VDELETE](@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @KeySQL VARCHAR(MAX)	
	DECLARE @CalleeView VARCHAR(MAX)
	DECLARE @Keys TABLE (CallerPropertyName varchar(50), CalleePropertyName varchar(50))
 
	SET @KeySQL = ''
 
	SELECT @CalleeView = QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name) from sys.objects WHERE object_id = @CalleeId
 
	INSERT INTO @Keys (CallerPropertyName,CalleePropertyName)
	SELECT CallerPropertyName,CalleePropertyName FROM QIC.KeyResolve_(@Token, @CallerId, @CalleeId, @TokenMap)
 
	SELECT @KeySQL += @CalleeView + '.' + QUOTENAME(CallerPropertyName) + ' = deleted.' + QUOTENAME(CalleePropertyName) + ' AND ' from QIC.KeyResolve_(@Token, @CallerId, @CalleeId, @TokenMap)
 
	IF LEN(@KeySQL) > 0
	BEGIN
		SET @KeySQL = LEFT(@KeySQL, DATALENGTH(@KeySQL) - DATALENGTH(' AND '))
 
		SET @Call = ''
		SET @Call += 
			QIC.Indent(@Indent) + 'DELETE ' + @CalleeView + QIC.LB() +
			QIC.Indent(@Indent) + 'FROM deleted'  + QIC.LB() +
			QIC.Indent(@Indent) + 'WHERE ' + @KeySQL
 
	END
 
	RETURN @Call
 
END
GO
CREATE FUNCTION [QIC].[CallFactory_VUPDATE](@Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Call VARCHAR(MAX) 
	DECLARE @UpdateSQL VARCHAR(MAX)
	DECLARE @Keys TABLE (CallerPropertyName varchar(50), CalleePropertyName varchar(50))	
	DECLARE @TargetToken QIC.TokenTable
	DECLARE @LocalToken QIC.TokenTable
	DECLARE @CalleeView VARCHAR(MAX)
	DECLARE @KeySQL VARCHAR(MAX)	
 
	SET @KeySQL = ''
	SET @UpdateSQL = ''
 
	INSERT INTO @TargetToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
	SELECT 0,0,0,token.ObjectId,0,token.PropertyId,token.PropertyName,0,0 FROM @Token token
	INNER JOIN sys.columns Targetcolumns
		ON Targetcolumns.object_id = token.ObjectId
		AND Targetcolumns.column_id = token.PropertyId
		AND Targetcolumns.is_computed = 0
		AND Targetcolumns.is_identity = 0
	WHERE token.ObjectId = @CalleeId
 
 
	INSERT INTO @LocalToken (IsOutPut,IsReadOnly,MaxLength,ObjectId,Precision,PropertyId,PropertyName,Scale,UserTypeId)
	SELECT 0,0,0,ObjectId,0,PropertyId,PropertyName,0,0 FROM @Token 
	WHERE ObjectId = @CallerId OR (PropertyName LIKE '@%') OR (PropertyName LIKE '''%''')
 
	SELECT @CalleeView = QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name) from sys.objects WHERE object_id = @CalleeId
	
	INSERT INTO @Keys (CallerPropertyName,CalleePropertyName)
	SELECT CallerPropertyName,CalleePropertyName FROM QIC.KeyResolve_(@Token, @CallerId, @CalleeId, @TokenMap)
 
	SELECT @UpdateSQL += 
		QUOTENAME(targetToken.PropertyName) + 
		'= ' + CASE LEFT(QIC.TokenSubstitute(@LocalToken, targetToken.PropertyName, @TokenMap),1) WHEN '@' THEN '' WHEN '''' THEN '' ELSE 'inserted.' END  + 
		QIC.TokenSubstitute(@LocalToken, targetToken.PropertyName, @TokenMap) + ', ' 
	FROM @TargetToken targetToken
	LEFT OUTER JOIN @Token sourceToken
		ON sourceToken.ObjectId = @CallerId
		AND QIC.TokenSubstitute(@LocalToken, sourceToken.PropertyName, @TokenMap) =  targetToken.PropertyName
	WHERE NOT EXISTS (select * from @Keys keys where keys.CallerPropertyName = targetToken.PropertyName)
 
	SELECT @KeySQL += @CalleeView + '.' + QUOTENAME(CallerPropertyName) + ' = inserted.' + QUOTENAME(CalleePropertyName) + ' AND ' FROM @Keys
 
	IF LEN(@KeySQL) > 0 AND LEN(@UpdateSQL) > 0
	BEGIN
		SET @KeySQL = LEFT(@KeySQL, DATALENGTH(@KeySQL) - DATALENGTH(' AND '))
		SET @UpdateSQL = LEFT(@UpdateSQL, DATALENGTH(@UpdateSQL) - DATALENGTH(', '))
 
		SET @Call = ''
		SET @Call += 
			QIC.Indent(@Indent) + 'UPDATE ' + @CalleeView + ' SET ' + @UpdateSQL + QIC.LB() +
			QIC.Indent(@Indent) + 'FROM inserted'  + QIC.LB() +
			QIC.Indent(@Indent) + 'WHERE ' + @KeySQL
 
	END
 
	RETURN @Call	
 
END
GO
CREATE FUNCTION [QIC].[CallFactory_] (@DelegateName varchar(50), @Token [QIC].[TokenTable] READONLY, @CallerId int, @CalleeId int, @ReturnPropertName varchar(50), @TokenMap varchar(50), @Indent int, @CalleeDelegateName varchar(50))
RETURNS varchar(MAX)
AS
BEGIN
 
	IF @DelegateName='FN'
	BEGIN
		RETURN [QIC].[CallFactory_FN] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='IF'
	BEGIN
		RETURN [QIC].[CallFactory_IF] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='P'
	BEGIN
		RETURN [QIC].[CallFactory_P] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='TF'
	BEGIN
		RETURN [QIC].[CallFactory_TF] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='V'
	BEGIN
		RETURN [QIC].[CallFactory_V] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='VINSERT'
	BEGIN
		RETURN [QIC].[CallFactory_VINSERT] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='VUPDATE'
	BEGIN
		RETURN [QIC].[CallFactory_VUPDATE] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
	IF @DelegateName='VDELETE'
	BEGIN
		RETURN [QIC].[CallFactory_VDELETE] (@Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
	END
 
	--DEFAULT
	RETURN NULL
 
END
GO
CREATE FUNCTION QIC.CallFactory(@ConfigName VARCHAR(50), @Token QIC.TokenTable READONLY, @CallerId INT, @CalleeId INT, @ReturnPropertName VARCHAR(50), @TokenMap VARCHAR(50), @Indent INT, @CalleeDelegateName varchar(50), @CallFactory VARCHAR(50))
RETURNS VARCHAR(MAX)
AS
BEGIN
 
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @CallType VARCHAR(50)
 
	SELECT @CallType = type FROM sys.objects WHERE object_id = @CalleeId
	SET @DelegateName = @CallType
 
	IF @CallType <> @CallFactory AND EXISTS (SELECT * FROM QIC.Delegate_(@ConfigName) WHERE InterfaceSchemaName = 'QIC' AND InterfaceName = 'CallFactory_' AND DelegateName = @CallFactory)
	BEGIN
		SET @DelegateName = @CallFactory
	END
	
	RETURN QIC.CallFactory_(@DelegateName, @Token, @CallerId, @CalleeId, @ReturnPropertName, @TokenMap, @Indent, @CalleeDelegateName)
 
END
GO
CREATE FUNCTION QIC.InterfaceFactory_P (@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @Parameters VARCHAR(MAX)
	DECLARE @ReturnToken VARCHAR(MAX)
	DECLARE @ObjectName VARCHAR(MAX)
	DECLARE @HasDelegateName BIT
	DECLARE @Implementation VARCHAR(MAX)
	DECLARE @Declare VARCHAR(MAX)
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @DelegateImplementation VARCHAR(MAX)
	DECLARE @HasDefault bit
 
	DECLARE @Token QIC.TokenTable
	DECLARE @Delegate TABLE (DelegateId INT, InterfaceId INT, DelegateName VARCHAR(50), InterfaceType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Aspect TABLE (AspectId INT, InterfaceId INT, DelegateName VARCHAR(50), ActionName VARCHAR(50), AspectReturnToken VARCHAR(50), SortOrder INT, AspectType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Call TABLE (Id INT IDENTITY(1,1), DelegateName VARCHAR(50), Call VARCHAR(MAX), ActionName varchar(50))
 
	SET @ReturnToken = '@InterfaceReturn'
 
	INSERT INTO @Aspect (InterfaceId,AspectId,DelegateName,ActionName,AspectReturnToken,SortOrder,AspectType, TokenMap, CallFactory)
	SELECT InterfaceId,AspectId,DelegateName, ActionName, AspectReturnToken,SortOrder,AspectType,TokenMap, CallFactory
	FROM QIC.Aspect_(@ConfigName) aspect
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Delegate (InterfaceId,DelegateId,DelegateName,InterfaceType,TokenMap, CallFactory)
	SELECT InterfaceId,DelegateId, DelegateName, InterfaceType, TokenMap, CallFactory
	FROM QIC.Delegate_(@ConfigName) delegate
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	VALUES (@InterfaceId, 0, @ReturnToken, TYPE_ID('INT'), 8,0,0,0,0)
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	WHERE parameters.object_id = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Delegate delegate
		ON delegate.DelegateId = parameters.object_id
 
	IF EXISTS (select * from @Token where PropertyName = '@DelegateName') 
	BEGIN
		SET @HasDelegateName = 1
	END
	ELSE
	BEGIN
		SET @HasDelegateName = 0
	END
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Aspect aspect
		ON aspect.AspectId = parameters.object_id
	WHERE parameters.parameter_id > 0
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct aspect.AspectId, returntoken.PropertyId, aspect.AspectReturnToken, returntoken.UserTypeId, returntoken.Precision, returntoken.Scale, returntoken.MaxLength, returntoken.IsOutPut, returntoken.IsReadOnly
	FROM @Aspect aspect
	CROSS APPLY QIC.ObjectReturnToken(AspectId) returntoken
 
	IF @HasDelegateName = 0 AND EXISTS (select * from @Token where PropertyName = '@DelegateName' and (PropertyId = 0 or IsOutPut = 1)) 
	BEGIN
		SET @HasDelegateName = 1
	END
 
	SELECT @ObjectName = QIC.ObjectName(@InterfaceId)
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT aspect.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT','') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName
	FROM @Aspect aspect
	WHERE aspect.ActionName = 'BEFORE'	
	ORDER BY aspect.SortOrder	
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT delegate.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, delegate.DelegateId, @ReturnToken, delegate.TokenMap, CASE WHEN delegate.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, delegate.DelegateName, delegate.CallFactory), 'DELEGATE'
	FROM @Delegate delegate
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT aspect.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName
	FROM @Aspect aspect
	WHERE aspect.ActionName = 'AFTER'	
	ORDER BY aspect.SortOrder	
 
	IF EXISTS(SELECT * FROM @Call WHERE DelegateName = 'DEFAULT') SET @HasDefault = 1
 
	SET @Parameters = ''
	SET @Implementation = ''
 
	SELECT @Parameters = QIC.InterfaceTokenDefine(@Token, @InterfaceId)
	SELECT @Declare = QIC.TokenDeclare(@Token,@InterfaceId, 1)
 
	BEGIN
		SET @DelegateImplementation = ''
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'BEFORE'
		ORDER BY Id
 
		IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
	END
 
	DECLARE callCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT distinct DelegateName FROM @Call WHERE DelegateName not in ('','DEFAULT') and @HasDelegateName = 1
 
	OPEN callCursor
 
	WHILE(1=1)
	BEGIN
		FETCH NEXT FROM callCursor INTO @DelegateName
		IF @@FETCH_STATUS <> 0 BREAK
 
		SET @DelegateImplementation = ''
 
		SET @DelegateImplementation += QIC.Indent(1) + 'IF @DelegateName=' + QUOTENAME(@DelegateName,'''') + QIC.LB()
		SET @DelegateImplementation += QIC.Indent(1) + 'BEGIN' + QIC.LB()
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = @DelegateName
		ORDER BY Id
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'AFTER'
		ORDER BY Id
 
		SET @DelegateImplementation += QIC.Indent(2) + 'RETURN ISNULL(' + @ReturnToken + ',0)' + QIC.LB()		
		SET @DelegateImplementation += QIC.Indent(1) + 'END'+ QIC.LB()
 
		SET @Implementation += @DelegateImplementation
 
	END
 
	CLOSE callCursor
	DEALLOCATE callCursor
 
	SET @Implementation += QIC.Indent(1) + '--DEFAULT' + QIC.LB()
	IF @HasDefault = 1
	BEGIN
		SELECT @Implementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = 'DEFAULT'
		ORDER BY Id

		SELECT @Implementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'AFTER'
		ORDER BY Id
 
	END
	SET @Implementation += QIC.Indent(1) + 'RETURN ISNULL(' + @ReturnToken + ',0)' + QIC.LB()		
 
 
	SET @Retval = 'ALTER PROCEDURE ' + @ObjectName + ' ' + @Parameters  +QIC.LB()
	SET @Retval += 'AS' + QIC.LB()
	SET @Retval += 'BEGIN' + QIC.LB()
	IF @Declare <> ''
	BEGIN
		SET @Retval += @Declare + QIC.LB()
	END
	SET @Retval += ISNULL(QIC.LB() + @Implementation +QIC.LB(),'')
	SET @Retval += 'END' 
 
 
	RETURN @Retval
 
END
GO
CREATE FUNCTION QIC.InterfaceFactory_IF (@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @Parameters VARCHAR(MAX)
	DECLARE @ObjectName VARCHAR(MAX)
	DECLARE @HasDelegateName BIT
	DECLARE @Implementation VARCHAR(MAX)
	DECLARE @NonDefaultDelegates VARCHAR(MAX)
	DECLARE @ReturnToken VARCHAR(MAX)
 
	DECLARE @Delegate TABLE (DelegateId INT, InterfaceId INT, DelegateName VARCHAR(50), InterfaceType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Token QIC.TokenTable
 
	INSERT INTO @Delegate (InterfaceId,DelegateId,DelegateName,InterfaceType,TokenMap, CallFactory)
	SELECT InterfaceId,DelegateId, DelegateName, InterfaceType, TokenMap, CallFactory
	FROM QIC.Delegate_(@ConfigName) delegate
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	WHERE parameters.object_id = @InterfaceId
	AND parameters.parameter_id <> 0
	ORDER BY parameters.parameter_id
 
	IF EXISTS (select * from @Token where PropertyName = '@DelegateName') 
	BEGIN
		SET @HasDelegateName = 1
	END
	ELSE
	BEGIN
		SET @HasDelegateName = 0
	END
 
	SELECT @ObjectName = QIC.ObjectName(@InterfaceId)
 
	SET @Parameters = ''
	SET @Implementation = ''
	SET @NonDefaultDelegates = ''
 
	SELECT @NonDefaultDelegates += '''' + delegate.DelegateName + ''','	FROM @Delegate delegate
 
	IF LEN(@NonDefaultDelegates) > 0 SET @NonDefaultDelegates = LEFT(@NonDefaultDelegates,LEN(@NonDefaultDelegates)-1)
 
	SELECT @Parameters += QIC.TokenDefine(parameters.name, user_type_id, precision, scale, max_length, is_output, is_readonly) + ', '
	FROM sys.parameters parameters
	WHERE parameters.object_id = @InterfaceId
	AND parameters.name <> ''
	ORDER BY parameter_id
 
	IF @Parameters <> '' SET @Parameters = LEFT(@Parameters,DATALENGTH(@Parameters) - 2)
 
	SELECT @Implementation += 
		QIC.CallFactory(@ConfigName,@Token, @InterfaceId, @InterfaceId,'','', 1, '', 'IF') + ' WHERE 1=0' +
		QIC.LB() + QIC.Indent(1) + 'UNION ALL' + QIC.LB() 
 
	SELECT @Implementation += 
		QIC.CallFactory(@ConfigName,@Token,delegate.InterfaceId, delegate.DelegateId,'',delegate.TokenMap, 1, delegate.DelegateName, delegate.CallFactory) +
		CASE @HasDelegateName 
			WHEN 1 THEN ' WHERE @DelegateName=' + QUOTENAME(delegate.DelegateName,'''') +  + ' ' 
			ELSE '' 
		END +
		QIC.LB() + QIC.Indent(1) + 'UNION ALL' + QIC.LB() 
	FROM @Delegate delegate
 
	IF @HasDelegateName = 1 AND EXISTS(SELECT * FROM @Delegate WHERE DelegateName = 'DEFAULT')
	BEGIN
		SELECT @Implementation += 
			QIC.CallFactory(@ConfigName,@Token,delegate.InterfaceId, delegate.DelegateId,'',delegate.TokenMap, 1, delegate.DelegateName, delegate.CallFactory) +
			CASE @HasDelegateName 
				WHEN 1 THEN ' WHERE @DelegateName NOT IN (' + @NonDefaultDelegates + ') ' 
				ELSE '' 
			END +
			QIC.LB() + QIC.Indent(1) + 'UNION ALL' + QIC.LB() 
		FROM @Delegate delegate
		WHERE DelegateName = 'DEFAULT'
	END
 
	IF @Implementation <> '' SET @Implementation = LEFT(@Implementation,DATALENGTH(@Implementation) - 11)
 
	IF @Implementation = ''
	BEGIN
		SET @Implementation += QIC.Indent(1) + QIC.CallFactory(@ConfigName,@Token,@InterfaceId, null,'',null, 1, '','IF') + ' WHERE 1 = 0'  + QIC.LB()
	END
 
	SET @Retval = 'ALTER FUNCTION ' + @ObjectName + '(' + @Parameters + ')' + QIC.LB()
	SET @Retval += 'RETURNS TABLE ' + QIC.LB()
	SET @Retval += 'AS' + QIC.LB()
	SET @Retval += 'RETURN' + QIC.LB()
	SET @Retval += '(' + QIC.LB()
	SET @Retval += ISNULL(@Implementation + QIC.LB(),'')		
	SET @Retval += ');' 
 
	RETURN @Retval
 
END
GO
CREATE FUNCTION QIC.InterfaceFactory_FN (@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @Parameters VARCHAR(MAX)
	DECLARE @ReturnToken VARCHAR(MAX)
	DECLARE @ObjectName VARCHAR(MAX)
	DECLARE @HasDelegateName BIT
	DECLARE @Implementation VARCHAR(MAX)
	DECLARE @Declare VARCHAR(MAX)
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @Returns VARCHAR(MAX)
	DECLARE @HasAspect BIT
	DECLARE @UseReturnToken BIT
	DECLARE @HasCalls BIT
	DECLARE @HasDefault BIT
	DECLARE @DelegateImplementation VARCHAR(MAX)
 
	DECLARE @Token QIC.TokenTable
	DECLARE @Delegate TABLE (DelegateId INT, InterfaceId INT, DelegateName VARCHAR(50), InterfaceType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Aspect TABLE (AspectId INT, InterfaceId INT, DelegateName VARCHAR(50), ActionName VARCHAR(50), AspectReturnToken VARCHAR(50), SortOrder INT, AspectType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Call TABLE (Id INT IDENTITY(1,1), DelegateName VARCHAR(50), Call VARCHAR(MAX), ActionName VARCHAR(50))
 
	SET @ReturnToken = '@InterfaceReturn'
 
	INSERT INTO @Aspect (InterfaceId,AspectId,DelegateName,ActionName,AspectReturnToken,SortOrder,AspectType, TokenMap, CallFactory)
	SELECT InterfaceId,AspectId,DelegateName, ActionName, AspectReturnToken,SortOrder,AspectType,TokenMap, CallFactory
	FROM QIC.Aspect_(@ConfigName) aspect
	WHERE InterfaceId = @InterfaceId
	AND AspectId <> @InterfaceId
 
	IF @@ROWCOUNT <> 0 SET @HasAspect = 1
	IF @HasAspect = 1 SET @UseReturnToken = 1
 
	INSERT INTO @Delegate (InterfaceId,DelegateId,DelegateName,InterfaceType,TokenMap, CallFactory)
	SELECT InterfaceId,DelegateId, DelegateName, InterfaceType, TokenMap, CallFactory
	FROM QIC.Delegate_(@ConfigName) delegate
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id , parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	WHERE parameters.object_id = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Delegate delegate
		ON delegate.DelegateId = parameters.object_id
 
	IF EXISTS (select * from @Token where PropertyName = '@DelegateName') 
	BEGIN
		SET @HasDelegateName = 1
	END
	ELSE
	BEGIN
		SET @HasDelegateName = 0
	END
	
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id , parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Aspect aspect
		ON aspect.AspectId = parameters.object_id
	WHERE parameters.parameter_id > 0
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct aspect.AspectId, returntoken.PropertyId, aspect.AspectReturnToken, returntoken.UserTypeId, returntoken.Precision, returntoken.Scale, returntoken.MaxLength, returntoken.IsOutPut, returntoken.IsReadOnly
	FROM @Aspect aspect
	CROSS APPLY QIC.ObjectReturnToken(AspectId) returntoken
 
	IF @HasDelegateName = 0 AND EXISTS (select * from @Token where PropertyName = '@DelegateName' and (PropertyId = 0 or IsOutPut = 1)) 
	BEGIN
		SET @HasDelegateName = 1
	END
 
	SELECT @ObjectName = QIC.ObjectName(@InterfaceId)
 
	IF @HasAspect = 1
	BEGIN
		INSERT INTO @Call (DelegateName,Call,ActionName)
		SELECT aspect.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT','') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '',aspect.CallFactory), aspect.ActionName
		FROM @Aspect aspect
		WHERE aspect.ActionName = 'BEFORE'	
		ORDER BY aspect.SortOrder	
	END
	
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT delegate.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, delegate.DelegateId, CASE @UseReturnToken WHEN 1 THEN @ReturnToken ELSE '' END, delegate.TokenMap, CASE WHEN delegate.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, delegate.DelegateName, delegate.CallFactory),'DELEGATE'
	FROM @Delegate delegate
 
	IF @@ROWCOUNT > 0 SET @HasCalls = 1
 
	IF @HasAspect = 1
	BEGIN
		INSERT INTO @Call (DelegateName,Call,ActionName)
		SELECT aspect.DelegateName, QIC.LB() + QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END,'', aspect.CallFactory), aspect.ActionName
		FROM @Aspect aspect
		WHERE aspect.ActionName = 'AFTER'	
		ORDER BY aspect.SortOrder	
	END
 
	IF EXISTS(SELECT * FROM @Call WHERE DelegateName = 'DEFAULT') SET @HasDefault = 1
 
	SET @Parameters = ''
	SET @Implementation = ''
	SET @Returns = ''
 
	SELECT @Parameters = QIC.InterfaceTokenDefine(@Token, @InterfaceId)
 
	SELECT @Returns = QIC.TokenDefine('', UserTypeId, Precision, Scale, MaxLength, 0, 0)
	FROM @Token 
	WHERE ObjectId = @InterfaceId
	AND PropertyId = 0
 
	IF ISNULL(@UseReturnToken,0) = 0
	BEGIN
		DELETE @Token WHERE PropertyId = 0
	END
 
	SELECT @Declare = QIC.TokenDeclare(@Token,@InterfaceId, 1)
 
	BEGIN
		SET @DelegateImplementation = ''
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'BEFORE'
		ORDER BY Id
 
		IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
	END
 
 
	DECLARE callCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT distinct DelegateName FROM @Call WHERE DelegateName not in ('','DEFAULT') and @HasDelegateName = 1
 
	OPEN callCursor
 
	WHILE(1=1)
	BEGIN
		FETCH NEXT FROM callCursor INTO @DelegateName
		IF @@FETCH_STATUS <> 0 BREAK
 
		SET @DelegateImplementation = ''
 
		SET @DelegateImplementation += QIC.Indent(1) + 'IF @DelegateName=' + QUOTENAME(@DelegateName,'''') + QIC.LB()
		SET @DelegateImplementation += QIC.Indent(1) + 'BEGIN' + QIC.LB()
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = @DelegateName
		ORDER BY Id
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'AFTER'
		ORDER BY Id
 
		IF @UseReturnToken = 1
		BEGIN
			SET @DelegateImplementation += QIC.Indent(2) + 'RETURN ' + @ReturnToken + QIC.LB()
		END
		SET @DelegateImplementation += QIC.Indent(1) + 'END'+ QIC.LB()
		SET @Implementation += @DelegateImplementation
 
	END
 
	CLOSE callCursor
	DEALLOCATE callCursor
 
	SET @Implementation += QIC.Indent(1) + '--DEFAULT' + QIC.LB()
	IF @HasDefault = 1
	BEGIN
		SELECT @Implementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = 'DEFAULT'
		ORDER BY Id

		SELECT @Implementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'AFTER'
		ORDER BY Id
	END
	IF @UseReturnToken = 1
	BEGIN
		SET @Implementation += QIC.Indent(1) + 'RETURN ' + @ReturnToken + QIC.LB()
	END
	ELSE
	BEGIN
		IF ISNULL(@HasDefault,0) = 0
		BEGIN
			SET @Implementation += QIC.Indent(1) + 'RETURN NULL' + QIC.LB()
		END
	END
 
	SET @Retval = 'ALTER FUNCTION ' + @ObjectName + ' (' + @Parameters + ')' + QIC.LB()
	SET @Retval += 'RETURNS ' + @Returns + QIC.LB()
	SET @Retval += 'AS' + QIC.LB()
	SET @Retval += 'BEGIN' + QIC.LB()
	IF @Declare <> ''
	BEGIN
		SET @Retval += @Declare + QIC.LB()
	END
 
	SET @Retval += ISNULL(QIC.LB() + @Implementation +QIC.LB(),'')
	SET @Retval += 'END' 
 
 
	RETURN @Retval
 
END
GO
CREATE FUNCTION QIC.InterfaceFactory_TF (@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @Parameters VARCHAR(MAX)
	DECLARE @ReturnToken VARCHAR(MAX)
	DECLARE @ObjectName VARCHAR(MAX)
	DECLARE @HasDelegateName BIT
	DECLARE @Implementation VARCHAR(MAX)
	DECLARE @Declare VARCHAR(MAX)
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @Returns VARCHAR(MAX)
	DECLARE @HasDefault BIT
	DECLARE @DelegateImplementation VARCHAR(MAX)
 
	DECLARE @Token QIC.TokenTable
	DECLARE @ReturnTokenTable QIC.TokenTable
	DECLARE @Delegate TABLE (DelegateId INT, InterfaceId INT, DelegateName VARCHAR(50), InterfaceType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Aspect TABLE (AspectId INT, InterfaceId INT, DelegateName VARCHAR(50), ActionName VARCHAR(50), AspectReturnToken VARCHAR(50), SortOrder INT, AspectType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Call TABLE (Id INT IDENTITY(1,1), DelegateName VARCHAR(50), Call VARCHAR(MAX), ActionName VARCHAR(50))
 
	SET @ReturnToken = '@InterfaceReturn'
 
	INSERT INTO @Aspect (InterfaceId,AspectId,DelegateName,ActionName,AspectReturnToken,SortOrder,AspectType, TokenMap, CallFactory)
	SELECT InterfaceId,AspectId,DelegateName, ActionName, AspectReturnToken,SortOrder,AspectType,TokenMap, CallFactory
	FROM QIC.Aspect_(@ConfigName) aspect
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Delegate (InterfaceId,DelegateId,DelegateName,InterfaceType,TokenMap, CallFactory)
	SELECT InterfaceId,DelegateId, DelegateName, InterfaceType, TokenMap, CallFactory
	FROM QIC.Delegate_(@ConfigName) delegate
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @ReturnTokenTable (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT columns.object_id, columns.column_id, columns.name, columns.user_type_id, columns.precision, columns.scale, columns.max_length,0, 0
	FROM sys.columns columns
	WHERE columns.object_id = @InterfaceId
	ORDER BY columns.column_id
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	WHERE parameters.object_id = @InterfaceId
	AND parameters.parameter_id <> 0
	ORDER BY parameters.parameter_id
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id, parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Delegate delegate
		ON delegate.DelegateId = parameters.object_id
 
	IF EXISTS (select * from @Token where PropertyName = '@DelegateName') 
	BEGIN
		SET @HasDelegateName = 1
	END
	ELSE
	BEGIN
		SET @HasDelegateName = 0
	END
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, case parameters.parameter_id WHEN 0 THEN @ReturnToken ELSE parameters.name END, parameters.user_type_id , parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Aspect aspect
		ON aspect.AspectId = parameters.object_id
	WHERE parameters.parameter_id > 0
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct aspect.AspectId, returntoken.PropertyId, aspect.AspectReturnToken, returntoken.UserTypeId, returntoken.Precision, returntoken.Scale, returntoken.MaxLength, returntoken.IsOutPut, returntoken.IsReadOnly
	FROM @Aspect aspect
	CROSS APPLY QIC.ObjectReturnToken(AspectId) returntoken
 
	IF @HasDelegateName = 0 AND EXISTS (select * from @Token where PropertyName = '@DelegateName' and (PropertyId = 0 or IsOutPut = 1)) 
	BEGIN
		SET @HasDelegateName = 1
	END
 
	SELECT @ObjectName = QIC.ObjectName(@InterfaceId)
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT aspect.DelegateName,  QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT','') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName
	FROM @Aspect aspect
	WHERE aspect.ActionName = 'BEFORE'	
	ORDER BY aspect.SortOrder	
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT delegate.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, delegate.DelegateId, @ReturnToken, delegate.TokenMap, CASE WHEN delegate.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, delegate.DelegateName, delegate.CallFactory), 'DELEGATE'
	FROM @Delegate delegate
 
	INSERT INTO @Call (DelegateName,Call,ActionName)
	SELECT aspect.DelegateName,  QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName = ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName  
	FROM @Aspect aspect
	WHERE aspect.ActionName = 'AFTER'	
	ORDER BY aspect.SortOrder	
 
	IF EXISTS(SELECT * FROM @Call WHERE DelegateName = 'DEFAULT') SET @HasDefault = 1
 
	SET @Parameters = ''
	SET @Implementation = ''
	SET @Returns = ''
 
	SELECT @Parameters = QIC.InterfaceTokenDefine(@Token, @InterfaceId)
	SELECT @Returns = @ReturnToken + ' TABLE (' + QIC.InterfaceTokenDefine(@ReturnTokenTable, @InterfaceId) + ')'
	SELECT @Declare = QIC.TokenDeclare(@Token,@InterfaceId, 1)
 
	BEGIN
		SET @DelegateImplementation = ''
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'BEFORE'
		ORDER BY Id
 
		IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
	END
 
	DECLARE callCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT distinct DelegateName FROM @Call WHERE DelegateName not in ('','DEFAULT') and @HasDelegateName = 1
 
	OPEN callCursor
 
	WHILE(1=1)
	BEGIN
		FETCH NEXT FROM callCursor INTO @DelegateName
		IF @@FETCH_STATUS <> 0 BREAK
 
		SET @DelegateImplementation = ''
 
		SET @DelegateImplementation += QIC.Indent(1) + 'IF @DelegateName=' + QUOTENAME(@DelegateName,'''') + QIC.LB()
		SET @DelegateImplementation += QIC.Indent(1) + 'BEGIN' + QIC.LB()
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = @DelegateName
		ORDER BY Id
 
		SELECT @DelegateImplementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = '' and ActionName = 'AFTER'
		ORDER BY Id
 
		SET @DelegateImplementation += QIC.Indent(2) + 'RETURN' + QIC.LB()
		SET @DelegateImplementation += QIC.Indent(1) + 'END'+ QIC.LB()
 
		SET @Implementation += @DelegateImplementation
 
	END
 
	SET @Implementation += QIC.Indent(1) + '--DEFAULT' + QIC.LB()
	IF @HasDefault = 1
	BEGIN
		SELECT @Implementation += Call + QIC.LB()
		FROM @Call
		WHERE DelegateName = 'DEFAULT'
		ORDER BY Id
	END
	SET @Implementation += QIC.Indent(1) + 'RETURN' + QIC.LB()
 
	CLOSE callCursor
	DEALLOCATE callCursor
 
	SET @Retval = 'ALTER FUNCTION ' + @ObjectName + ' (' + @Parameters + ')' + QIC.LB()
	SET @Retval += 'RETURNS ' + @Returns + QIC.LB()
	SET @Retval += 'AS' + QIC.LB()
	SET @Retval += 'BEGIN' + QIC.LB()
	IF @Declare <> ''
	BEGIN
		SET @Retval += @Declare + QIC.LB()
	END
 
	SET @Retval += ISNULL(QIC.LB() + @Implementation +QIC.LB(),'')
	SET @Retval += 'END' 
 
	RETURN @Retval
 
END
GO
CREATE FUNCTION [QIC].[InterfaceFactory_V] (@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @Retval VARCHAR(MAX)
	DECLARE @ObjectName VARCHAR(MAX)
	DECLARE @HasDelegateName BIT
	DECLARE @Implementation VARCHAR(MAX)
	DECLARE @TriggerName varchar(200)
	DECLARE @TriggerAction varchar(10)
	DECLARE @Declare VARCHAR(MAX)
	DECLARE @DelegateImplementation VARCHAR(MAX)
	DECLARE @NonDefaultDelegates VARCHAR(MAX)
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @TriggerObjectName VARCHAR(200)
	DECLARE @SchemaName VARCHAR(50)

	SELECT @SchemaName = SCHEMA_NAME(schema_id) FROM sys.objects WHERE object_id = @InterfaceId

	DECLARE @Triggers TABLE (Action VARCHAR(10), Name VARCHAR(100))
 
	DECLARE @Delegate TABLE (DelegateId INT, InterfaceId INT, DelegateName VARCHAR(50), InterfaceType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Aspect TABLE (AspectId INT, InterfaceId INT, DelegateName VARCHAR(50), ActionName VARCHAR(50), AspectReturnToken VARCHAR(50), SortOrder INT, AspectType VARCHAR(50), TokenMap VARCHAR(50), CallFactory VARCHAR(50))
	DECLARE @Token QIC.TokenTable
	DECLARE @Call TABLE (Id INT IDENTITY(1,1), DelegateName VARCHAR(50), Call VARCHAR(MAX), ActionName varchar(50))

	INSERT INTO @Aspect (InterfaceId,AspectId,DelegateName,ActionName,AspectReturnToken,SortOrder,AspectType, TokenMap, CallFactory)
	SELECT InterfaceId,AspectId,DelegateName, ActionName, AspectReturnToken,SortOrder,AspectType,TokenMap, CallFactory
	FROM QIC.Aspect_(@ConfigName) aspect
	WHERE InterfaceId = @InterfaceId
	AND aspect.DelegateName = ''
 
	INSERT INTO @Delegate (InterfaceId,DelegateId,DelegateName,InterfaceType,TokenMap, CallFactory)
	SELECT InterfaceId,DelegateId, DelegateName, InterfaceType, TokenMap, CallFactory
	FROM QIC.Delegate_(@ConfigName) delegate
	WHERE InterfaceId = @InterfaceId
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT columns.object_id, columns.column_id, columns.name, columns.user_type_id, columns.precision, columns.scale, columns.max_length, 0, 0
	FROM sys.columns columns
	WHERE columns.object_id = @InterfaceId
	ORDER BY columns.column_id
 
	IF EXISTS (select * from @Token where PropertyName = 'DelegateName') 
	BEGIN
		SET @HasDelegateName = 1
	END
	ELSE
	BEGIN
		SET @HasDelegateName = 0
	END
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct columns.object_id, columns.column_id, columns.name, columns.user_type_id, columns.precision, columns.scale, columns.max_length, 0, 0
	FROM sys.columns columns
	INNER JOIN @Delegate delegate
		ON delegate.DelegateId = columns.object_id
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct parameters.object_id, parameters.parameter_id, parameters.name, parameters.user_type_id , parameters.precision, parameters.scale, parameters.max_length, parameters.is_output, parameters.is_readonly
	FROM sys.parameters parameters
	INNER JOIN @Aspect aspect
		ON aspect.AspectId = parameters.object_id
	WHERE parameters.parameter_id > 0
 
	INSERT INTO @Token (ObjectId, PropertyId, PropertyName, UserTypeId, Precision, Scale, MaxLength, IsOutPut, IsReadOnly)
	SELECT distinct aspect.AspectId, returntoken.PropertyId, aspect.AspectReturnToken, returntoken.UserTypeId, returntoken.Precision, returntoken.Scale, returntoken.MaxLength, returntoken.IsOutPut, returntoken.IsReadOnly
	FROM @Aspect aspect
	CROSS APPLY QIC.ObjectReturnToken(AspectId) returntoken
 
	SELECT @ObjectName = QIC.ObjectName(@InterfaceId)

	SET @Implementation = ''
	SELECT @Implementation += 
		QIC.CallFactory(@ConfigName,@Token, @InterfaceId, @InterfaceId,'','', 1, '', 'V') + ' WHERE 1=0' +
		QIC.LB() + QIC.Indent(1) + 'UNION ALL' + QIC.LB() 
 
	SELECT @Implementation += 
		QIC.CallFactory(@ConfigName,@Token,delegate.InterfaceId, delegate.DelegateId,'',delegate.TokenMap, 1, delegate.DelegateName, delegate.CallFactory) +
		QIC.LB() + QIC.Indent(1) + 'UNION ALL' + QIC.LB() 
	FROM @Delegate delegate
	WHERE @HasDelegateName = 1 OR delegate.DelegateName = 'DEFAULT'
 
	IF @Implementation <> '' SET @Implementation = LEFT(@Implementation,DATALENGTH(@Implementation) - 11)
 
	SET @NonDefaultDelegates = ''
	IF @HasDelegateName = 1
	BEGIN
		SELECT @NonDefaultDelegates += QUOTENAME(DelegateName,'''') + ',' from @Delegate delegate where DelegateName <> 'DEFAULT'
		IF @NonDefaultDelegates <> '' SET @NonDefaultDelegates = LEFT(@NonDefaultDelegates,DATALENGTH(@NonDefaultDelegates) - 1)
	END
 
	SET @Retval = 'ALTER VIEW ' + @ObjectName + QIC.LB()
	SET @Retval += 'AS' + QIC.LB()
	SET @Retval += ISNULL(@Implementation + QIC.LB(),'')		
	SET @Retval += 'GO' + QIC.LB()
 
	SET @TriggerName = UPPER(REPLACE(REPLACE(REPLACE(@ObjectName,']',''),'[',''),'.','_'))
 
	INSERT INTO @Triggers (Action,Name) VALUES 
	('INSERT', 'QIC_INSERT_' + @TriggerName),
	('DELETE', 'QIC_DELETE_' + @TriggerName),
	('UPDATE', 'QIC_UPDATE_' + @TriggerName)
 
	DECLARE triggerCursor CURSOR LOCAL FOR
	SELECT Name FROM @Triggers
 
	OPEN triggerCursor
 
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM triggerCursor INTO @TriggerName
		IF @@FETCH_STATUS <> 0 BREAK
		SET @TriggerObjectName = QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TriggerName)
		SET @Retval += 'IF OBJECT_ID(''' + @TriggerObjectName + ''') IS NOT NULL DROP TRIGGER ' + @TriggerObjectName + QIC.LB()
	END
 
	CLOSE triggerCursor
	DEALLOCATE triggerCursor
 
	-- RENDER TRIGGERS
	BEGIN
 
		DECLARE triggerCursor CURSOR LOCAL FAST_FORWARD FOR
		SELECT Name,Action FROM @Triggers
 
		OPEN triggerCursor
 
		WHILE (1=1)
		BEGIN
			FETCH NEXT FROM triggerCursor INTO @TriggerName, @TriggerAction
			IF @@FETCH_STATUS <> 0 BREAK
 
			SET @Implementation = ''
			SET @DelegateImplementation = ''
			SET @Declare = ''
 
			SELECT @Declare = QIC.TokenDeclare(@Token,@InterfaceId, 1)
 
			DELETE @Call
 
			INSERT INTO @Call (DelegateName,Call,ActionName)
			SELECT aspect.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT','') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName
			FROM @Aspect aspect
			WHERE aspect.ActionName IN ('BEFORE','BEFORE ' + @TriggerAction)
			ORDER BY aspect.SortOrder	
 
			INSERT INTO @Call (DelegateName,Call,ActionName)
			SELECT delegate.DelegateName, QIC.CallFactory(@ConfigName,@Token,delegate.InterfaceId, delegate.DelegateId,'',delegate.TokenMap, 1, delegate.delegatename, delegate.CallFactory + @TriggerAction) + 
					CASE @HasDelegateName 
						WHEN 1 THEN 
							CASE @TriggerAction WHEN 'INSERT' THEN ' WHERE ' ELSE ' AND ' END +
							CASE @TriggerAction WHEN 'DELETE' THEN 'deleted.' ELSE 'inserted.' END +
							CASE delegate.DelegateName WHEN 'DEFAULT' 
								THEN 'DelegateName NOT IN (' + @NonDefaultDelegates + ')'
								ELSE 'DelegateName = ' + QUOTENAME(delegate.delegatename,'''')
							END
						ELSE '' 
					END + 
					QIC.LB()
					,'DELEGATE'
			FROM @Delegate delegate
 
			INSERT INTO @Call (DelegateName,Call,ActionName)
			SELECT aspect.DelegateName, QIC.CallFactory(@ConfigName, @Token, @InterfaceId, aspect.AspectId, aspect.AspectReturnToken, aspect.TokenMap, CASE WHEN aspect.DelegateName IN ('DEFAULT') OR @HasDelegateName = 0 THEN 1 ELSE 2 END, '', aspect.CallFactory), aspect.ActionName
			FROM @Aspect aspect
			WHERE aspect.ActionName IN ('AFTER','AFTER ' + @TriggerAction)
			ORDER BY aspect.SortOrder	
 
			BEGIN
				SET @DelegateImplementation = ''
 
				SELECT @DelegateImplementation += Call + QIC.LB()
				FROM @Call
				WHERE DelegateName = '' and ActionName IN ('BEFORE','BEFORE ' + @TriggerAction)
				ORDER BY Id
 
				IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
			END
			
			BEGIN
				SET @DelegateImplementation = ''
 
				SELECT @DelegateImplementation += Call + QIC.LB()
				FROM @Call
				WHERE ActionName IN ('DELEGATE') and Call <> ''
				ORDER BY Id
 
				IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
			END
 
 
			BEGIN
				SET @DelegateImplementation = ''
 
				SELECT @DelegateImplementation += Call + QIC.LB()
				FROM @Call
				WHERE DelegateName = '' and ActionName IN ('AFTER','AFTER ' + @TriggerAction)
				ORDER BY Id
 
				IF @DelegateImplementation <> '' SET @Implementation += @DelegateImplementation + QIC.LB()
			END
 
			SET @Retval += 'GO' + QIC.LB()
			SET @Retval += 'CREATE TRIGGER ' + @TriggerName + ' ON ' + @ObjectName + QIC.LB()
			SET @Retval += 'INSTEAD OF ' + @TriggerAction + ' ' + QIC.LB()
			SET @Retval += 'AS' + QIC.LB()
			SET @Retval += 'BEGIN' + QIC.LB()
			SET @Retval += 'SET NOCOUNT ON' + QIC.LB()
			IF @Declare <> ''
			BEGIN
				SET @Retval += @Declare + QIC.LB()
			END
			SET @Retval += ISNULL(@Implementation + QIC.LB(),'')		
			SET @Retval += QIC.Indent(1)+ 'RETURN' + QIC.LB()
			SET @Retval += 'END' + QIC.LB()
 
 
		END
 
		CLOSE triggerCursor
		DEALLOCATE triggerCursor
 
	END
 
	RETURN @Retval
 
END
GO
CREATE FUNCTION [QIC].[InterfaceFactory_] (@DelegateName varchar(50), @ConfigName varchar(50), @InterfaceId int)
RETURNS nvarchar(MAX)
AS
BEGIN
 
	IF @DelegateName='FN'
	BEGIN
		RETURN [QIC].[InterfaceFactory_FN] (@ConfigName, @InterfaceId)
	END
	IF @DelegateName='IF'
	BEGIN
		RETURN [QIC].[InterfaceFactory_IF] (@ConfigName, @InterfaceId)
	END
	IF @DelegateName='P'
	BEGIN
		RETURN [QIC].[InterfaceFactory_P] (@ConfigName, @InterfaceId)
	END
	IF @DelegateName='TF'
	BEGIN
		RETURN [QIC].[InterfaceFactory_TF] (@ConfigName, @InterfaceId)
	END
	IF @DelegateName='V'
	BEGIN
		RETURN [QIC].[InterfaceFactory_V] (@ConfigName, @InterfaceId)
	END
	--DEFAULT
	RETURN NULL
 
END
GO
CREATE FUNCTION QIC.InterfaceFactory(@ConfigName VARCHAR(50), @InterfaceId INT)
RETURNS NVARCHAR(MAX)
AS
BEGIN
 
	DECLARE @DelegateName VARCHAR(50)
	DECLARE @InterfaceType VARCHAR(50)
	DECLARE @InterfaceFactory VARCHAR(50)
 
	SELECT @InterfaceFactory = InterfaceFactory, @InterfaceType = InterfaceType FROM QIC.Interface_(@ConfigName) WHERE InterfaceId = @InterfaceId
 
	SET @DelegateName = @InterfaceType
 
	IF @InterfaceType <> @InterfaceFactory AND EXISTS (SELECT * FROM QIC.Delegate_(@ConfigName) WHERE InterfaceSchemaName = 'QIC' AND InterfaceName = 'InterfaceFactory_' AND DelegateName = @InterfaceFactory)
	BEGIN
		SET @DelegateName = @InterfaceFactory
	END
 
	RETURN QIC.InterfaceFactory_(@DelegateName,@ConfigName,@InterfaceId)
END
GO
CREATE PROCEDURE QIC.CompileInterface @InterfaceName VARCHAR(200), @ConfigName VARCHAR(50) = NULL
AS
BEGIN
	
	DECLARE @Script NVARCHAR(MAX)
	DECLARE @InterfaceId INT
	DECLARE @ScriptFragment NVARCHAR(MAX)
	DECLARE @ScriptSplit NVARCHAR(10)
 
	SELECT @InterfaceId = InterfaceId FROM QIC.Interface_(@ConfigName) WHERE InterfaceName = @InterfaceName
 
	SET @Script = QIC.InterfaceFactory(@ConfigName, @InterfaceId)
	SET @ScriptSplit = QIC.LB() + 'GO' + QIC.LB()
 
	DECLARE scriptCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT String FROM QIC.[Split](@Script,@ScriptSplit)
 
	OPEN scriptCursor
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM scriptCursor INTO @ScriptFragment
		IF @@FETCH_STATUS <> 0 BREAK
 
		EXEC (@ScriptFragment)
 
	END
 
	CLOSE scriptCursor
	DEALLOCATE scriptCursor
 
END
GO
CREATE PROCEDURE QIC.LongPrint @String NVARCHAR(MAX)
AS
BEGIN
	DECLARE @CurrentEnd BIGINT
	DECLARE @Offset tinyint
 
	SET @String = replace(  replace(@string, char(13) + char(10), char(10))   , char(13), char(10))
 
	WHILE LEN(@String) > 1
	BEGIN
		IF CHARINDEX(CHAR(10), @String) between 1 AND 4000
		BEGIN
			SET @CurrentEnd =  CHARINDEX(char(10), @String) -1
			SET @Offset = 2
		END
		ELSE
		BEGIN
			SET @CurrentEnd = 4000
			SET @Offset = 1
		END   
		PRINT SUBSTRING(@String, 1, @CurrentEnd) 
		set @string = SUBSTRING(@String, @CurrentEnd+@Offset, LEN(@String))   
	END 
 
END
GO
CREATE PROCEDURE QIC.Compile @ConfigName VARCHAR(50) = NULL
AS
BEGIN
 
	DECLARE @InterfaceName VARCHAR(200)
 
	DECLARE interfaceCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT interface.InterfaceName FROM QIC.Interface_(@ConfigName) interface
	WHERE interface.SchemaName <> 'QIC'
 
	OPEN interfaceCursor
 
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM interfaceCursor INTO @InterfaceName
		IF @@FETCH_STATUS <> 0 BREAK
 
		EXEC QIC.CompileInterface @InterfaceName = @InterfaceName, @ConfigName = @ConfigName
 
	END
 
	CLOSE interfaceCursor
	DEALLOCATE interfaceCursor
 
END
GO
CREATE PROCEDURE QIC.CompileInternal @ConfigName VARCHAR(50) = NULL
AS
BEGIN
 
	DECLARE @InterfaceName VARCHAR(200)
 
 
 
	DECLARE interfaceCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT interface.InterfaceName FROM QIC.Interface_(@ConfigName) interface
	WHERE interface.SchemaName = 'QIC'
 
	OPEN interfaceCursor
 
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM interfaceCursor INTO @InterfaceName
		IF @@FETCH_STATUS <> 0 BREAK
 
		EXEC QIC.CompileInterface @InterfaceName = @InterfaceName, @ConfigName = @ConfigName
 
	END
 
	CLOSE interfaceCursor
	DEALLOCATE interfaceCursor
 
END
GO
 
CREATE PROCEDURE QIC.ScriptInterface @InterfaceName VARCHAR(200), @ConfigName VARCHAR(50) = NULL
AS
BEGIN
	
	DECLARE @InterfaceId INT
	DECLARE @Script NVARCHAR(MAX)
 
	SELECT @InterfaceId = InterfaceId FROM QIC.Interface_(@ConfigName) WHERE InterfaceName = @InterfaceName
 
	SET @Script = QIC.InterfaceFactory(@ConfigName, @InterfaceId) + QIC.LB() + 'GO' + QIC.LB()
 
	EXEC QIC.LongPrint @Script
 
END
GO
CREATE PROCEDURE QIC.ScriptInternal @ConfigName VARCHAR(50) = NULL
AS
BEGIN
 
	DECLARE @InterfaceName VARCHAR(200)
 
	DECLARE interfaceCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT interface.InterfaceName FROM QIC.Interface_(@ConfigName) interface
	WHERE interface.SchemaName = 'QIC'
 
	OPEN interfaceCursor
 
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM interfaceCursor INTO @InterfaceName
		IF @@FETCH_STATUS <> 0 BREAK
 
		EXEC QIC.ScriptInterface @InterfaceName = @InterfaceName, @ConfigName = @ConfigName
 
	END
 
	CLOSE interfaceCursor
	DEALLOCATE interfaceCursor
 
END
GO
CREATE PROCEDURE QIC.Script @ConfigName VARCHAR(50) = NULL
AS
BEGIN
 
	DECLARE @InterfaceName VARCHAR(200)
 
	DECLARE interfaceCursor CURSOR LOCAL FAST_FORWARD FOR
	SELECT interface.InterfaceName FROM QIC.Interface_(@ConfigName) interface
	WHERE interface.SchemaName <> 'QIC'
 
	OPEN interfaceCursor
 
	WHILE (1=1)
	BEGIN
		FETCH NEXT FROM interfaceCursor INTO @InterfaceName
		IF @@FETCH_STATUS <> 0 BREAK
 
		EXEC QIC.ScriptInterface @InterfaceName = @InterfaceName, @ConfigName = @ConfigName
 
	END
 
	CLOSE interfaceCursor
	DEALLOCATE interfaceCursor
 
END
GO


PRINT 'COMPILE'
BEGIN
	EXEC QIC.CompileInternal
END
GO
